标签:style class blog http tar ext
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2229
题意:给定一个带权无向图。若干询问,每个询问回答有多少点对(s,t)满足s和t的最小割小于等于x。
思路:对于两个点(s,t)的最小割。这个最小割将将所有点分成左右两个集合X、Y。对于X中任意一点a与Y中任意一点b,(a,b)的最小割小于等于(s,t)的最小割。因此,每次递归计算分成的两个集合的最小割,更新答案。
struct node
{
int v,cap,next;
};
node edges[N*N*10];
int head[N],e;
void add(int u,int v,int cap)
{
edges[e].v=v;
edges[e].cap=cap;
edges[e].next=head[u];
head[u]=e++;
}
void Add(int u,int v,int cap)
{
add(u,v,cap);
add(v,u,0);
}
int pre[N],cur[N],num[N],h[N];
int Maxflow(int s,int t,int n)
{
int i;
for(i=0;i<=n;i++) cur[i]=head[i],num[i]=h[i]=0;
int u=s,Min,k,v;
int ans=0;
while(h[u]<n)
{
if(u==t)
{
Min=INF;
for(i=s;i!=t;i=edges[cur[i]].v)
{
k=cur[i];
if(edges[k].cap<Min) Min=edges[k].cap,v=i;
}
ans+=Min; u=v;
for(i=s;i!=t;i=edges[cur[i]].v)
{
k=cur[i];
edges[k].cap-=Min;
edges[k^1].cap+=Min;
}
}
for(i=cur[u];i!=-1;i=edges[i].next)
{
if(edges[i].cap>0&&h[u]==h[edges[i].v]+1) break;
}
if(i!=-1)
{
cur[u]=i;
pre[edges[i].v]=u;
u=edges[i].v;
}
else
{
if(--num[h[u]]==0) break;
k=n;
cur[u]=head[u];
for(i=head[u];i!=-1;i=edges[i].next)
{
if(edges[i].cap>0&&h[edges[i].v]<k)
{
k=h[edges[i].v];
}
}
num[k+1]++;
h[u]=k+1;
if(u!=s) u=pre[u];
}
}
return ans;
}
int List[N][N],a[N][N],p[N][N];
int n,m;
int MinCut[N][N];
int b[N];
void build(int s,int t)
{
clr(head,-1); e=0;
int i,j,u,v;
FOR1(i,n)
{
u=i;
for(j=1;j<=List[u][0];j++)
{
v=List[u][j];
if(u!=t&&v!=s) Add(u,v,a[u][v]);
}
}
}
int visit[N];
void DFS(int u)
{
visit[u]=1;
int i,v;
for(i=head[u];i!=-1;i=edges[i].next)
{
v=edges[i].v;
if(edges[i].cap>0&&!visit[v]) DFS(v);
}
}
void DFS(int L,int R)
{
if(L==R) return;
int s=b[L],t=b[R];
build(s,t);
int temp=Maxflow(s,t,n);
clr(visit,0); DFS(s);
int i,j,u,v,X[N],Y[N],xNum=0,yNum=0;
for(i=L;i<=R;i++)
{
if(visit[b[i]]) X[++xNum]=b[i];
else Y[++yNum]=b[i];
}
FOR1(i,n) if(visit[i]) FOR1(j,n) if(!visit[j])
{
u=i; v=j;
MinCut[u][v]=MinCut[v][u]=min(MinCut[u][v],temp);
}
FOR1(i,xNum) b[L+i-1]=X[i];
FOR1(j,yNum) b[L+xNum+j-1]=Y[j];
DFS(L,L+xNum-1);
DFS(L+xNum,R);
}
int main()
{
rush()
{
RD(n,m);
int i,j,u,v,w;
FOR1(i,n) List[i][0]=0;
clr(a,0); clr(p,0);
FOR1(i,m)
{
RD(u,v,w);
if(!p[u][v])
{
List[u][++List[u][0]]=v;
List[v][++List[v][0]]=u;
p[u][v]=p[v][u]=1;
}
a[u][v]+=w;
a[v][u]+=w;
}
FOR1(i,n) b[i]=i;
FOR1(i,n) FOR1(j,n) MinCut[i][j]=INF;
DFS(1,n);
int Q,x,ans;
RD(Q);
while(Q--)
{
RD(x); ans=0;
FOR1(i,n) for(j=i+1;j<=n;j++) if(MinCut[i][j]<=x) ans++;
PR(ans);
}
puts("");
}
}
标签:style class blog http tar ext
原文地址:http://www.cnblogs.com/jianglangcaijin/p/3799782.html