zoukankan      html  css  js  c++  java
  • 增广路算法

    #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;    
    } 
  • 相关阅读:
    【JavaScript数据结构系列】04-优先队列PriorityQueue
    【JavaScript数据结构系列】02-栈Stack
    【JavaScript数据结构系列】01-数组Array
    【JavaScript数据结构系列】00-开篇
    2019个人年度总结
    批处理·命令行中常用的操作
    flutter 环境出错后排查
    [图解算法]线性时间选择Linear Select——<递归与分治策略>
    阿里云轻量应用服务器——配置MySQL远程连接(踩坑,LAMP+CentOS)
    [知识复习] C语言文件读写
  • 原文地址:https://www.cnblogs.com/zuimeiyujianni/p/9016146.html
Copyright © 2011-2022 走看看