增广路算法

#include<queue>
#include<cstdio> 
#include<iostream>
#include<cstring>
using namespace std;

const int maxn = 20;
const int INF = (1<<30);

int cap[maxn][maxn],flow[maxn][maxn];//cap记录容量,flow记录流量
int m;  //弧的数量

int EdmondsKarp(int s,int t)
{
    int p[maxn],a[maxn];
    queue<int>q;
    
    memset(flow,0,sizeof(flow)); //初始化流量数组
    int f=0;
    
    while(true)
    {
        memset(a,0,sizeof(a));
        
        a[s]=INF;
        
        q.push(s);
        
        while(!q.empty())//BFS找增广路 
        {
            int u=q.front(); q.pop();
            
            for(int v=1;v<=n;v++) 
            if(!a[v] && cap[u][v]>flow[u][v]) //由于a[i]总是正数,所以使用a[i]代替vis数组。
            {
                //找新的节点v 
                p[v]=u; q.push(v);
                a[v]=min(a[u],cap[u][v]-flow[u][v]);    
            }     
        }
        
        if(a[t] == 0) break; //找不到,说明当前流已经是最大流
        
        for(int u=t;u!=s;u=p[u]) 
        {
            flow[p[u]][u] += a[t];//更新正向流量 
            flow[u][p[u]] -= a[t];//更新反向流量 
        }
        
        f += a[t]; //更新从s流出的流量 
    }
    
    return f;
     
}

int main(void)
{
    cin >> m;
    int u,v;
    for(int i=1;i<=m;i++)
    {
        cin >> u >> v;
        cin >> cap[u+1][v+1];
        cap[v+1][u+1]=0;    
    } 
    
    int f = EdmondsKarp(1,6);
    
    cout<< f;
    
    return 0; 
}


/*
10 
0 1 8 
0 2 4 
1 3 2 
1 4 2 
2 1 4 
2 3 1 
2 4 4 
3 4 6 
3 5 9 
4 5 7
*/

结果为8

 

//紫书上面的方法,使用邻接表更加快速一些
#include<cstdio>
#include<iostream> 
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>

const int maxn = 20;
const int INF = 0xFFFFFFF;

using namespace std;

struct 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];       //G[i]保存顶点i出发的所有的边的编号 
    
    int a[maxn];              //用来计算路径的流量 
    int p[maxn];              //p[u]记录到达顶点u的边的编号 
    
    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] == 0 ) 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 main(void)
{
    int m;
    EdmondsKarp ek;
    cin >> ek.n;
    ek.init(ek.n);
    cin >> m;
    for(int i=0;i<m;i++)
    {
        int u,v,cap;
        cin >> u >> v >> cap;
        ek.AddEdge(u,v,cap);    
    }
    int ans = ek.MaxFlow(0,ek.n-1);
    cout << ans;
    
    return 0;    
} 

 

posted @ 2018-05-09 19:23  最美遇见你  阅读(309)  评论(0编辑  收藏  举报