#include<stdio.h> #include<queue> #include<string.h> using namespace std; #define inf 0x3fffffff #define N 200 struct node { int v,w,next; }bian[N*N*2],fbian[N*N*2]; int head[N],yong,tt; int deep[N];//深度保留层次图 void addedge(int u,int v,int w) { bian[yong].v=v; bian[yong].w=w; bian[yong].next=head[u]; head[u]=yong++; } int bfs(int s) {//寻找层次图 int i,cur; queue<int>q; memset(deep,-1,sizeof(deep)); q.push(s); deep[s]=1; while(!q.empty()) { cur=q.front(); q.pop(); for(i=head[cur];i!=-1;i=bian[i].next) if(bian[i].w&&deep[bian[i].v]==-1) { deep[bian[i].v]=deep[cur]+1; q.push(bian[i].v); } } if(deep[tt]!=-1)return 1; return 0; } int Min(int a,int b) { return a>b?b:a; } int dfs(int s,int limit) {//多次dfs int i,cost=0,flow,v; // printf("%d %d\n",s,head[s]); if(s==tt) {return limit;} for(i=head[s];i!=-1;i=bian[i].next) { v=bian[i].v; // printf("%d %d %d\n",s,v,bian[i].w); if(bian[i].w&&deep[v]==deep[s]+1) { // printf("%d\n",v); flow=dfs(v,Min(limit-cost,bian[i].w)); if(flow>0) { bian[i].w-=flow; bian[i^1].w+=flow; cost+=flow; if(limit==cost)break; } else deep[v]=-1;//如果再次遇到v就不会进行下去 } } return cost ; } int dinic_maxflow(int s) {//dinic算法模板 int sum=0; while(bfs(1)) { //for(i=1;i<=tt;i++) // printf("%d\n",deep[i]); sum+=dfs(1,inf); } return sum; } /*int visit[N]; void dfs1(int u) { int i; visit[u]=1; for(i=head[u];i!=-1;i=bian[i].next) { if(bian[i].w&&visit[bian[i].v]==0) dfs1(bian[i].v); } }*/ int ds[N],dds,dt[N],ddt; int fhead[N],fyong; int main() { int t,m,n,i,j,k,maxflow,ma,fma,fa,fb; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); yong=0; memset(head,-1,sizeof(head)); while(m--) { scanf("%d%d%d",&i,&j,&k); addedge(i,j,k);//加入边 addedge(j,i,0);//退边 } tt=n; maxflow=dinic_maxflow(1);//最大流模板 dds=0;ddt=0; /* memset(visit,0,sizeof(visit)); dfs1(1);*/ for(i=2;i<n;i++) {//根据deep是否为-1可以得到源点集和汇点集 if(deep[i]!=-1)//源点集 ds[++dds]=i; else dt[++ddt]=i;//汇点集 } // printf("%d %d\n",dds,ddt); /* for(i=2;i<n;i++) { if(visit[i]) ds[++dds]=i; else dt[++ddt]=i; }*/ for(i=0;i<yong;i++)//保留残留网络 fbian[i]=bian[i]; for(i=1;i<=n;i++)//保留残留网络 fhead[i]=head[i]; ma=0; fyong=yong;//保留残留网络 for(i=1;i<=dds;i++)//枚举 for(j=1;j<=ddt;j++) { fa=ds[i];fb=dt[j]; for(k=0;k<yong;k++)//加入了新边,必须跟新为原来的求最大流一次的残留网络 bian[k]=fbian[k]; memset(head,0,sizeof(head)); for(k=1;k<=n;k++) //因为加入了新边,所以必须跟新head的值为原来的残留网络 head[k]=fhead[k]; yong=fyong;// addedge(fa,fb,inf); addedge(fb,fa,0); fma=dinic_maxflow(1); if(fma>ma)//求出最大值 ma=fma; } printf("%d\n",ma+maxflow); } return 0; }