刘汝佳紫书-EdmondsKarp算法解决最大流问题

来源:互联网 发布:淘宝女装前十名网红 编辑:程序博客网 时间:2024/06/09 17:33

学习理解:

#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <queue>#include <climits>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int Maxn=503;const int MaxHashSize=(1<<16)+3;const LL LLMax=((1LL<<62)-1+(1LL<<62));const double eps=1e-9;const double PI=atan(1.0)*4.0;const int INF=2139062143;const int MemsetBigNum=127;///对于 int数组 可以得到  2139062143  INT_MAX = 2147483647struct Edge{    int from,to,cap,flow;    Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f) {}};struct EdmondsKarp{    int n,m;    vector<Edge> edges;    vector<int> G[Maxn];    int a[Maxn];    int p[Maxn];    void init(int n)    {        this->n=n;        for(int i=0; i<n; i++)            G[i].clear();        edges.clear();    }    void AddEdge(int from,int to,int cap)    {        edges.push_back(Edge(from,to,cap,0));        edges.push_back(Edge(to,from,0,0));        m=edges.size();        G[from].push_back(m-2);        G[to].push_back(m-1);    }    int Maxflow(int s,int t)    {        int flow=0;        while(true)        {            memset(a,0,sizeof(a));            queue<int>Q;            Q.push(s);            a[s]=INF;            while(!Q.empty())            {                int x=Q.front();                Q.pop();                for(int i=0; i<G[x].size(); i++)                {                    Edge &e=edges[G[x][i]];                    if(!a[e.to]&&e.cap>e.flow)///这里 a[e.to]当 vis 数组使用                    {                        p[e.to]=G[x][i];              ///记录路径                        a[e.to]=min(a[x],e.cap-e.flow);                        Q.push(e.to);                    }                }                if(a[t])break;///找到一条通往 t 的路,并且可以增广            }            if(!a[t])                break;            cout << "p[t]: " << p[t] << endl;            for(int u=t; u!=s; u=edges[p[u]].from)            {                edges[p[u]].flow+=a[t];                edges[p[u]^1].flow-=a[t];///这里减去是有必要的,有可能会出现一些作为中转站的节点            }            for(int i=0;i<m;i++)                cout << i << " from: " << edges[i].from << "\tto: " << edges[i].to << "\tflow: " << edges[i].flow << endl;            for(int i=0; i<n; i++)                cout << "i: " << i << "\ta: " << a[i] << endl;            cout << endl;            flow+=a[t];///加上本次增广量        }        return flow;    }};int n,m;EdmondsKarp edmondsKarp;int main(void){    freopen("input.txt","r",stdin);//    freopen("output.txt","w",stdout);    ios::sync_with_stdio(false);    while(cin >> n >> m,n||m)    {        edmondsKarp.init(n);        cout << "n: " << n << "\tm: " << m << endl;        for(int i=0; i<m; i++)        {            cout << i << endl;            int from,to,cap;            cin >> from >> to >> cap;            edmondsKarp.AddEdge(from,to,cap);        }        cout << edmondsKarp.Maxflow(0,n-1) << endl;    }    return 0;}


给出一组数据(紫书 P366 的那个图):

6 90 1 160 2 132 1 41 3 123 2 92 4 144 3 73 5 204 5 40 0
PS:感觉那个图有问题。。。 v1 指向 v2 的 10 是什么意思???我给去掉了

0 0