zoukankan      html  css  js  c++  java
  • HDU 1532 Drainage Ditches EK算法 flod算法

    题意:
    输入m n, m是边数,n是点数。
    接下来m行: 起点,终点,容量。
    求以 1 为源点, n为汇点的最大流。

    #include<stdio.h>
    #include<string.h>
    #include<queue>
    #include<algorithm>
    using namespace std;
    
    const int INF = 0xfffffff;
    const int MAXN = 200 + 10;
    
    //邻接矩阵存放图。
    int flow[MAXN][MAXN];
    //mark[]标记是否访问过,pre[]记录增广路。
    int mark[MAXN], pre[MAXN];
    int m, n, f; //f为最大流。
    
    void max_flow()
    {
        //不断寻找增广路,知道找不到为止,找不到的标志为 mark[n]==0. 
        while(1) {
            memset(mark, 0, sizeof(mark));
            memset(pre, 0, sizeof(pre));
    
            queue<int> Q;
            mark[1] = 1;
            Q.push(1);
            while( !Q.empty() ) {
                int cnt = Q.front();
                Q.pop();
                //找到增广路,跳出。
                if(cnt == n) {
                    break;
                }
    
                for(int i = 1; i <= n; i++) {
                    if(!mark[i] && flow[cnt][i] > 0) {
                        mark[i] = 1;
                        Q.push(i);
                        pre[i] = cnt;
                    }
                }
            }
    
            //如果没找到可增广的路,直接跳出.
            if( !mark[n] ) {
                break;
            }
    
            //计算该增广路最大可增加的流量.
            int minx = INF;
            for(int i = n; i != 1; i = pre[i]) {
                minx = min( flow[pre[i]][i], minx );
            }
    
            for(int i = n; i != 1; i = pre[i]) {
                flow[pre[i]][i] -= minx; //更新正向流量。
                flow[i][pre[i]] += minx; //更新反向流量。
            }
            f += minx;
        }
    }
    
    int main()
    {
        while(scanf("%d %d", &m, &n) != EOF) {
            memset(flow, 0, sizeof(flow));
            for(int i = 0; i < m; i++) {
                int u, v, len;
                scanf("%d %d %d", &u, &v, &len);
                //这个题有重边的情况,所以要flow[u][v] += len;直接等于过不去。
                flow[u][v] += len;
            }
            f = 0;
            max_flow();
            printf("%d
    ", f);
        }
        return 0;
    }
    
    

     

    上面是EK、
    下面是flod 还有一个区别就是 上面用邻接矩阵,而下面用邻接表。
        #include <cstdio>  
        #include <cstring>  
        #include <iostream>  
        #include <string>  
        #include <algorithm>  
        #include <map>  
        #include <vector>  
        using namespace std;  
        const int N = 1100;  
        const int INF = 0x3f3f3f3f;  
          
        struct Node  
        {  
            int to;//终点  
            int cap; //容量  
            int rev;  //反向边  
        };  
          
        vector<Node> v[N];  
        bool used[N];  
          
        void add_Node(int from,int to,int cap)  //重边情况不影响  
        {  
            v[from].push_back((Node){to,cap,v[to].size()});  
            v[to].push_back((Node){from,0,v[from].size()-1});  
        }  
          
        int dfs(int s,int t,int f)  
        {  
            if(s==t)  
                return f;  
            used[s]=true;  
            for(int i=0;i<v[s].size();i++)  
            {  
                Node &tmp = v[s][i];  //注意  
                if(used[tmp.to]==false && tmp.cap>0)  
                {  
                    int d=dfs(tmp.to,t,min(f,tmp.cap));  
                    if(d>0)  
                    {  
                        tmp.cap-=d;  
                        v[tmp.to][tmp.rev].cap+=d;  
                        return d;  
                    }  
                }  
            }  
            return 0;  
        }  
          
        int max_flow(int s,int t)  
        {  
            int flow=0;  
            for(;;){  
                memset(used,false,sizeof(used));  
                int f=dfs(s,t,INF);  
                if(f==0)  
                    return flow;  
                flow+=f;  
            }  
        }  
        int main()  
        {  
            int n,m;  
            while(~scanf("%d%d",&n,&m))  
            {  
                memset(v,0,sizeof(v));  
                for(int i=0;i<n;i++)  
                {  
                    int x,y,z;  
                    scanf("%d%d%d",&x,&y,&z);  
                    add_Node(x,y,z);  
                }  
                printf("%d
    ",max_flow(1,m));  
            }  
        }  
    
    

     

    另附这题大神BLOG:http://blog.csdn.net/y990041769/article/details/22276101

  • 相关阅读:
    坐标转换convertRect
    error this is not a media message!!!
    嵌入式-第一季-第4课
    嵌入式-第一季-第2课
    嵌入式-第一季-第3课
    嵌入式-第一季-第1课
    web-15. 事件与函数
    web-14. 表达式与程序流程
    web-13. 数组和字符串
    数据-第5课-线性表的本质
  • 原文地址:https://www.cnblogs.com/s1124yy/p/5645818.html
Copyright © 2011-2022 走看看