//网络流——最大流 //终止条件是——残量网络中找不到增广路 //此题还需要考虑多重边的情况 #include<iostream> #include<queue> #include<cstring> #define INF 2000000000 using namespace std; int n,m,u,v,x,y,c,st,ed; int flow[205][205],cap[205][205];//当前流量,最大容量 int rflow[205],pre[205];//rflow为每个结点的残余流量,顺便当vis数组 int maxflow; int main() { //freopen("in.txt","r",stdin); while(scanf("%d%d",&m,&n) != EOF) { maxflow = 0; st = 1; ed = n; memset(flow,0,sizeof(flow)); memset(cap,0,sizeof(cap)); for(int i = 0;i < m;++i) { scanf("%d%d%d",&x,&y,&c); cap[x][y] += c;//由于题目会出现多重边,用邻接矩阵保存比较方便,所以用+=将最大流量叠加上去 } for(;;) { queue<int> q; memset(rflow,0,sizeof(rflow)); rflow[st] = INF;//起点的流设置为无限 q.push(st); while(!q.empty()) { u = q.front(); q.pop(); for(v = 1;v <= n;++v) { if(!rflow[v] && cap[u][v] > flow[u][v])//如果残余流量等于0(说明未被更新过)且当前容量大于当前流量,则说明改点可以拓展 { pre[v] = u;//前驱指针记录 q.push(v);//加入队列 rflow[v] = min(rflow[u],cap[u][v] - flow[u][v]);//该点的残余流量为(流入点残余流量)和(当前容量和当前流量之差)的最小值 } } } if(rflow[ed] == 0) break;//找不到可以到汇点的增广路,跳出 for(u = ed;u != st;u = pre[u])//从汇点往回更新流量 { flow[pre[u]][u] += rflow[ed];//更新正向流量 flow[u][pre[u]] -= rflow[ed];//更新反向流量 } maxflow += rflow[ed];//更新总最大流 } printf("%d/n",maxflow); } return 0; }