• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
ACM s1124yy
守りたいものが 強くさせること
博客园    首页    新随笔    联系   管理     

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\n", 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\n",max_flow(1,m));  
        }  
    }  

 

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

posted @ 2016-07-06 09:42  s1124yy  阅读(208)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3