这里的边是单向的。。。因为水流不可逆。 打成双向边wrong了一下。。
给不愿看题目的孩子看题意:
第一行:N,M代表N条边,M个点
下面N行 u,v,cap :u点到v点的流限cap
问从1点(源点)到M点(汇点)的最大流
水流是不会寻找方向的,所以找到的可行流都是水会流过的地方Ps:能流水都流,不能流就已满,BFS判断能否流,并用pre数组记录这条可行流。
裸裸的题,裸裸的码
#include <stdio.h> #include <string.h> #include <vector> #include <queue> using namespace std; #define N 205 #define M 205 #define INF 1<<30 struct node{ int from,to,flow,cap;//flow代表这条边还可以流过多少水,cap代表流上限 }edge[M*2],E; vector<int>G[N]; int e;//汇点 int d[N],edgenum;//网络流的层次 int pre[N];//记录一条允许流,pre[i]代表连接i点的边 inline int Min(int a,int b){return a>b?b:a;} void addedge(int u,int v,int cap){ E.from=u,E.to=v,E.cap=cap,E.flow=cap; edge[edgenum]=E; G[u].push_back(edgenum++); } bool BFS(){ queue<int>q;while(!q.empty())q.pop(); memset(d,-1,sizeof(d)); q.push(1); d[1]=0; while(!q.empty()){ int u=q.front();q.pop(); for(int i=0;i<G[u].size();i++) { int v=edge[G[u][i]].to; if(d[v]==-1&&edge[G[u][i]].flow>0) { d[v]=d[u]+1; pre[v]=G[u][i];//边的编号 if(v==e)return true; q.push(v); } } } return false; } int change(){ int liu=INF;//代表这条可行流的最大值 for(int i=e;i!=1;i) { int num=pre[i]; liu=Min(liu,edge[num].flow);//这条可行流的上限是每条边剩余的flow的值 i=edge[num].from; } for(int i=e;i!=1;){ int num=pre[i]; edge[num].flow-=liu;//减少这条可行流中每条边可以流过的水量 i=edge[num].from; } return liu; } int solve(){ int res=0; while(BFS()){ res+=change(); } return res; } int main(){ int bian,i; while(~scanf("%d%d",&bian,&e)){ for(i=1;i<=e;i++)G[i].clear(); edgenum=0; for(i=0;i<bian;i++) { int u,v,cap,temp;scanf("%d%d%d",&u,&v,&cap); addedge(u,v,cap); } int ans=solve(); printf("%d\n",ans); } return 0; }