poj 1273 最大流 ford-fulkerson
来源:互联网 发布:淘宝店铺联盟是什么 编辑:程序博客网 时间:2024/04/29 05:25
#include <iostream>#include <cstdio>#include <queue>#include <cstring>using namespace std;#define MAXN 210struct Matrix{ int c,f; //容量,流量};int M,N;Matrix Edge[MAXN][MAXN]; //流网络int s,t;int residual[MAXN][MAXN]; //残留网络int qu[MAXN*MAXN],qs,qe; //队列int pre[MAXN]; //记录增广路的前一个节点int vis[MAXN]; //标记增广路int maxflow,min_augment; //最大流,可改进量void find_augment_path() //BFS寻找增广路{ int i,cu; memset(vis,0,sizeof(vis)); // memset(pre,0,sizeof(pre)); qs = 0; qu[qs] = s; pre[s] = s; vis[s] = 1; qe = 1; memset(residual,0,sizeof(residual)); memset(pre,0,sizeof(pre)); while(qs < qe && pre[t] == 0) { cu = qu[qs]; for(int i = 1; i <= N; i++){ if(vis[i] == 0) { if(Edge[cu][i].c - Edge[cu][i].f > 0){ residual[cu][i] = Edge[cu][i].c - Edge[cu][i].f; pre[i] = cu; qu[qe++] = i; vis[i] = 1;} else if(Edge[i][cu].f > 0){ residual[cu][i] = Edge[i][cu].f; pre[i] = cu; qu[qe++] = i; vis[i] = 1;} }} qs++; }}void augment_flow() //计算改进量{ int i = t,j; if(pre[i] == 0) //如果不存在增广路 { min_augment = 0; return; } j = 0x7fffffff; //设置j为无穷大 while(i != s) //倒向追踪 { if(residual[pre[i]][i] < j) //如果存在残留网络{ j = residual[pre[i]][i]; //计算增广路上最小残留值即为改进量} i = pre[i]; } min_augment = j;}void update_flow() //更新网络流{ int i = t; if(pre[i] == 0) //如果没有增广路 return; while(i != s) { if(Edge[pre[i]][i].c - Edge[pre[i]][i].f > 0){ Edge[pre[i]][i].f += min_augment;} else if(Edge[i][pre[i]].f > 0){ Edge[pre[i]][i].f -= min_augment;} i = pre[i]; }}void Ford() //增广路算法{ s = 1; t = N; maxflow = 0; while(1) { find_augment_path(); augment_flow(); maxflow += min_augment; if(min_augment > 0) //如果有增广路update_flow(); else //如果没有增广路return; }}int main(){ int i; int u,v,c; while(scanf("%d%d",&M,&N) != EOF) { memset(Edge,0,sizeof(Edge)); for(i = 0; i < M; i++){ cin>>u>>v>>c; Edge[u][v].c += c;} Ford(); cout<<maxflow<<endl; } return 0;}