POJ1273 最大流模板题 初学网络流~

来源:互联网 发布:public static json 编辑:程序博客网 时间:2024/05/17 18:25

题意 不细说了,就是源是1,汇点是m的最大流模板

思路 初学网络流,拿这题练练手。

  总结下EdmondsKarp算法几个要注意的点:

           (1)算法本质就是利用BFS不停地找增广路,直到找不到为止。

           (2)每次BFS后更新增广路时,一定注意减去或加上的都是最后Terminal得到流量。

           (3)用连接表存的时候,为了把平行边存在相邻位置上,可能会增加平行边,为了避免这一点,可以在输入的时候做些处理,不过对最大流来说感觉不处理也不会有什么太大问题。当然用邻接矩阵来存就好办了,对平行边累加流量就好了。


                对这题来说,就是注意输入是多组的.....还有有平行边的存在


#include <iostream>#include <cstdio>#include <algorithm>#include <queue>#include <cstring>using namespace std;#define maxn 205#define maxm 500const int inf = 0x3f3f3f3f;struct Edge{int fr,to,val;int next;Edge(int fr=0,int to=0,int val=0,int next=-1):fr(fr),to(to),val(val),next(next){}void set(int f=0,int t=0,int v=0,int n=-1){fr = f;to = t;val = v;next = n;}}edge[maxm];int g[maxn];int n,m;void addEdge(){int f,t,v,i,j;int now = 0;memset(g,-1,sizeof(g));for(i=0;i<m;i++){scanf("%d%d%d",&f,&t,&v);edge[now].set(f,t,v,g[f]);g[f] = now++;//这里这样处理会造成重边 edge[now].set(t,f,0,g[t]);g[t] = now++;}} int flow[maxn];int path[maxn];int bfs(int st,int ter){memset(path,-1,sizeof(path));flow[st] = inf;queue<int> q;q.push(st);while(q.size()!=0 && path[ter] ==-1){int now = q.front();q.pop();for(int e = g[now];e != -1;e=edge[e].next){//若这点被访问过或者这条边残量为0则跳过 if(path[edge[e].to]!=-1 || edge[e].val==0 || edge[e].to == st)continue;flow[edge[e].to] = min(flow[now],edge[e].val); path[edge[e].to] = e;q.push(edge[e].to);}}while(q.size())q.pop();if(path[ter] == -1)return -1;return flow[ter];}int EdmondsKarp(int st,int ter){int sum = 0;path[st] = -1;while(bfs(st,ter)>=0){sum += flow[ter];//构建新的残量图 for(int e=path[ter];e!=-1;e=path[edge[e].fr]){edge[e].val -= flow[ter];edge[e^1].val += flow[ter];}}return sum;}int main(){while(scanf("%d%d",&m,&n)==2){addEdge();cout<<EdmondsKarp(1,n)<<endl;}return 0;}



邻接矩阵实现

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <queue>#include <algorithm>using namespace std;const int maxn = 900;const int maxm = 10000;const int inf = 0x3f3f3f3f;struct EdmondsKarp{//用到外部变量maxn,maxm,具体使用不非得按照模板 int n,m;int g[maxn][maxn];int flow[maxn];int path[maxn];queue<int> q; void init(int nn=0){n = nn;memset(g,0,sizeof(g));memset(flow,0,sizeof(flow));memset(path,-1,sizeof(path));}void addOne(int u,int v,int yuan){g[u][v] += yuan;m += 2; }int bfs(int s,int t){int i;memset(path,-1,sizeof(path));flow[s] = inf;//如果不加这句话,bfs内部就要一共三个判断 path[s] = s; q.push(s);while(q.size()>0){int tmp = q.front();q.pop();//这里i从0开始还是1开始,视情况而定 for(i=0;i<n;i++){if(g[tmp][i]>0 && path[i]==-1){flow[i] = min(g[tmp][i],flow[tmp]);path[i] = tmp;q.push(i);if(i==t){break;}}}if(path[t] != -1)break;}while(q.size()>0)q.pop();if(path[t] == -1)return 0;elsereturn flow[t];}int go(int s,int t){int ret = 0;while(bfs(s,t)){int now = path[t];int pre = t;ret += flow[t];while(pre != s){g[now][pre] -= flow[t];g[pre][now] += flow[t];pre = now;now = path[now];}}return ret;}}edk;int main(){int n,m;while(scanf("%d%d",&m,&n) == 2){edk.init(n);for(int i=0;i<m;i++){int u,v,c;scanf("%d%d%d",&u,&v,&c);edk.addOne(u-1,v-1,c);}cout<<edk.go(0,n-1)<<endl;}}



0 0