标签: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