hdu 1532 Drainage Ditches(最大流,Edmond Karp)

来源:互联网 发布:yii 连接数据库 编辑:程序博客网 时间:2024/06/10 04:46

前段时间看最大流,一直没看懂反向弧,直接导致我一蹶不振,昏沉了一段时间。最近又看最大流,找到了一篇不错的入门文章,我终于看懂反向弧了大笑

文章地址:http://www.wutianqi.com/?p=3107

代码直接套的刘汝佳紫书的模板,一点都没改动

#include <cstdio>#include <vector>#include <queue>#include <cstring>#include <algorithm>using namespace std;#define maxn 300#define INF 99999999struct Edge{    Edge(int u, int v, int c, int f):from(u),to(v),cap(c),flow(f){}    int from,to,cap,flow;};struct EdmondsKarp{    int n,m;    vector<Edge> edges;      vector<int> G[maxn];        int a[maxn];    int p[maxn];    void init(int 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;        for(;;)        {            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)                    {                        p[e.to] = G[x][i];                        a[e.to] = min(a[x],e.cap-e.flow);                        Q.push(e.to);                    }                }                if(a[t]) break;            }            if(!a[t]) break;            for(int u = t; u != s; u = edges[p[u]].from)            {                edges[p[u]].flow += a[t];                edges[p[u]^1].flow -= a[t];            }            flow += a[t];        }        return flow;    }};int N,M;int a,b,c;int main(){    while(scanf("%d%d",&N,&M)!=EOF)    {        EdmondsKarp EK;        EK.init(N);        for(int i=0;i<N;i++)        {            scanf("%d%d%d",&a,&b,&c);            EK.AddEdge(a,b,c);        }        printf("%d\n",EK.Maxflow(1,M));    }    return 0;}

下边代码套的那篇文章的模板

#include <iostream>#include <queue>#include <algorithm>using namespace std;const int msize = 205;int N, M; // N–路径数, M–结点数int r[msize][msize]; //int pre[msize]; // 记录结点i的前向结点为pre[i]bool vis[msize]; // 记录结点i是否已访问// 用BFS来判断从结点s到t的路径上是否还有delta// 即判断s,t之间是否还有增广路径,若有,返回1bool BFS(int s, int t){    queue<int> que;    memset(pre, -1, sizeof(pre));    memset(vis, false, sizeof(vis));    pre[s] = s;    vis[s] = true;    que.push(s);    int p;    while(!que.empty())    {        p = que.front();        que.pop();        for(int i=1; i<=M; ++i)        {            if(r[p][i]>0 && !vis[i])            {                pre[i] = p;                vis[i] = true;                if(i == t) // 存在增广路径                    return true;                que.push(i);            }        }    }    return false;}int EK(int s, int t){    int maxflow = 0, d;    while(BFS(s, t))    {        d= INT_MAX;// 若有增广路径,则找出最小的delta        for(int i=t; i!=s; i=pre[i])            d = min(d, r[pre[i]][i]);// 这里是反向边,看讲解        for(int i=t; i!=s; i=pre[i])        {            r[pre[i]][i] -= d;            r[i][pre[i]] += d;        }        maxflow += d;    }    return maxflow;}int main(){    while(cin >> N >> M)    {        memset(r, 0, sizeof(r));        int s, e, c;        for(int i=0; i<N; ++i)        {            cin >> s >> e >> c;            r[s][e] += c; // 有重边时则加上c        }        cout << EK(1, M) << endl;    }    return 0;}


0 0
原创粉丝点击