题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4280
#include <stdio.h> #include <string.h> #define MAXN 100002 #define MAXE 400002 #define INF 0x3f3f3f3f struct node { int from,to,next; int cap; }edge[MAXE]; int n,m,tot,src,dest,Queue[MAXN],cur[MAXN],Stack[MAXN];; int head[MAXN],level[MAXN],gap[MAXN];//gap[x]=y :说明残留网络中level[i]==x的个数为y void addEdge(int u,int v,int w) { edge[tot].from=u; edge[tot].to=v; edge[tot].cap=w; edge[tot].next=head[u]; head[u]=tot++; edge[tot].from=v; edge[tot].to=u; edge[tot].cap=0; edge[tot].next=head[v]; head[v]=tot++; } void BFS() { int front,rear,i,u,v; memset(level,-1,sizeof(level)); memset(gap,0,sizeof(gap)); gap[0]=1;//说明此时有1个level[i] = 0 front=rear=0; level[dest]=0; Queue[rear++]=dest; while(front<rear) { u=Queue[front++]; for(i=head[u];i!=-1;i=edge[i].next) { v=edge[i].to; if(level[v]!=-1||edge[i].cap!=0) continue; Queue[rear++]=v; level[v]=level[u]+1; ++gap[level[v]]; } } } int SAP() { int maxflow=0,i=0,u,top=0; BFS(); memcpy(cur,head,sizeof(head)); u=src; while(level[src]<n) { if(u==dest) { int inser,temp=INF; for(i=0;i!=top;++i) { if(temp>edge[Stack[i]].cap) { temp=edge[Stack[i]].cap; inser=i; } } for(i=0;i!=top;++i) { edge[Stack[i]].cap-=temp; edge[Stack[i]^1].cap+=temp; } maxflow+=temp; top=inser; u=edge[Stack[top]].from; } if(u!=dest&&gap[level[u]-1]==0) break;//出现断层,无增广路 for(i=cur[u];i!=-1;i=edge[i].next) {//遍历与u相连的未遍历结点 if(edge[i].cap!=0&&level[u]==level[edge[i].to]+1)//层序关系, 找到允许 break; } if(i!=-1)//找到允许弧 { cur[u]=i; Stack[top++]=i;//加入路径栈 u=edge[i].to;//查找下一个结点 } else//无允许的路径,修改标号 当前点的标号比与之相连的点中最小的多1 { int mixn=n; for(i=head[u];i!=-1;i=edge[i].next) {//找到与u相连的v中level[v]最小的点 if(edge[i].cap==0) continue; if(mixn>level[edge[i].to]) { mixn=level[edge[i].to]; cur[u]=i;//最小标号就是最新的允许弧 } } --gap[level[u]]; level[u]=mixn+1; ++gap[level[u]]; if(u!=src) u=edge[Stack[--top]].from; } } return maxflow; } int main() { int test,ans,i,m,x,y,w; int minx,maxx; scanf("%d",&test); while(test--) { minx=INF; maxx=~INF+1; /*n=Scan(); m=Scan();*/ scanf("%d %d",&n,&m); for(i=1;i<=n;++i) { /*x=Scan(); y=Scan();*/ scanf("%d %d",&x,&y); if(minx>=x) { minx=x; src=i; } if(maxx<=x) { maxx=x; dest=i; } } tot=0; memset(head,-1,sizeof(head)); while(m--) { /*x=Scan(); y=Scan(); w=Scan();*/ scanf("%d %d %d",&x,&y,&w); addEdge(x,y,w); addEdge(y,x,w); } ans=SAP(); printf("%d\n",ans); } return 0; }