题目链接: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;
}