zoukankan      html  css  js  c++  java
  • HDU1532 网络流最大流【EK算法】(模板题)

    <题目链接>

    题目大意:

    一个农夫他家的农田每次下雨都会被淹,所以这个农夫就修建了排水系统,还聪明的给每个排水管道设置了最大流量;首先输入两个数n,m ;n为排水管道的数量,m为节点的数量,接下来就是n行数,每一行分为x1,x2,x3;x1,x2为节点的序号,x3为流量;然后问从1号节点到m号节点的最大流是多少?

    解题分析:

    网络流最大流裸题,下面用的是EK算法,bfs起搜索增广路径的作用,EK算法比较难理解的地方就是反向边的构造。

    #include <cstdio>
    #include <cmath>
    #include <queue>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    int n,m;
    int map1[205][205];
    int pre[205];
    int vis[205];
    int s,t;
    
    bool BFS()               //bfs搜索增广路径 
    {
        int i,cur;
        queue<int>q;
        memset(pre,0,sizeof(pre));
        memset(vis,0,sizeof(vis));
        vis[s]=1;
        q.push(s);
        while(!q.empty())
        {
            cur=q.front();
            q.pop();
            if(cur==t)          
                return 1;            //如果搜索到终点,说明搜到一条增广路,return 1; 
            for(i=1; i<=n; i++)
            {
                if(!vis[i] &&map1[cur][i])
                {
                    q.push(i);
                    pre[i]=cur;       
                    vis[i]=1;
                }
            }
        }
        return 0;            //没有搜到一条完整的增广路 
    }
    
    int Max_flow()
    {
        int i,ans=0;
        while(1)
        {
            if(!BFS())      
                return ans;           //如果找不到增广路径了,此时ans算得的就是最大流 
                
            int Min=0x3f3f3f3f;
            for(i=t; i!=s; i=pre[i])     //遍历该条增广路径 
                Min=min(Min,map1[pre[i]][i]);      //找增广路径上的最小流量 
                
            for(i=t; i!=s; i=pre[i])
            {
                map1[pre[i]][i]-=Min;        //该条增广路径上的每条边都减去 min 
                map1[i][pre[i]]+=Min;        //该条增广路径上每条边修改反向边,反向边起到一种退流回溯的作用 
            }
            ans+=Min;
        }
    }
    int main()
    {
        while(scanf("%d %d",&m,&n)!=EOF)
        {
            memset(map1,0,sizeof(map1));
            s=1,t=n;
            while(m--)
            {
                int u,v,c;
                scanf("%d%d%d",&u,&v,&c);
                map1[u][v]+=c;
            }
           printf("%d
    ",Max_flow());
        }
        return 0;
    }

    2018-08-14

  • 相关阅读:
    7-20 (样卷)统计单词的个数 (40 分)
    7-21 删除字符 (30 分)
    7-19 计算有n个字符串中最长的字符串长度 (40 分)
    7-16 列表数字元素加权和(1) (40 分)
    7-17 列表元素个数的加权和(1) (40 分)
    7-15 求出歌手的得分 (40 分)
    7-10 jmu-python-异常-学生成绩处理基本版 (15 分)
    7-11 jmu-python-分段函数&数学函数 (15 分)
    7-12 产生每位数字相同的n位数 (30 分)
    7-9 jmu-python-异常-学生成绩处理专业版 (25 分)
  • 原文地址:https://www.cnblogs.com/00isok/p/9474504.html
Copyright © 2011-2022 走看看