HDU 3549 Flow Problem(网络流Dinic)

题目描述:给予一张图,源点 1,汇点 n 求最大流。

标准模板题,附上封装好的Dinic模板。

 

#include <algorithm>
#include <iostream>
#include <cstring>
#include <queue>
#include <map>
#include <set>

using namespace std;
#define N 5005
#define inf 0x3f3f3f3f
typedef long long ll;

class graphic{
public:
    void init(){
        memset(head,-1, sizeof(head));
        cnt = 0;
    }
    void add(int u,int v,int d){
        _add(u,v,d);
        _add(v,u,0);
    }
    long long Dinic(){
        long long ans = 0;
        while (bfs()){
            ans+=dfs(st,0x3f3f3f3f);
        }
        return ans;
    }
    void setST(int a,int b){///设置源汇点
        st = a,en = b;
    }
private:
    struct E{
        int to,next,val;
    }edge[N];
    int head[20],cnt,dep[20];
    bool dfsVis[20];
    int st,en;
    void _add(int u,int v,int d){
        edge[cnt].val = d;
        edge[cnt].to = v;
        edge[cnt].next = head[u];
        head[u] = cnt++;
    }
    bool bfs(){
        memset(dfsVis, false, sizeof(dfsVis));
        memset(dep,-1, sizeof(dep));
        queue<int>qq;
        qq.push(st);
        dep[st] = 0;
        while (!qq.empty()){
            int u = qq.front();
            qq.pop();
            for(int i = head[u],v ; ~i ; i = edge[i].next){
                v = edge[i].to;
                if(edge[i].val and -1==dep[v] ){
                    dep[v] = dep[u]+1;
                    qq.push(v);
                }
            }
        }
        return dep[en]!=-1;
    }
    int dfs(int u,int f){
        if(u==en){
            return f;
        }
        dfsVis[u] = true;
        int a;
        for(int i = head[u],v;~i ; i = edge[i].next){
            v = edge[i].to;
            if(edge[i].val and !dfsVis[v] and dep[v] == dep[u]+1 and (a = dfs(v,min(f,edge[i].val)))){
                edge[i].val-=a;
                edge[i^1].val+=a;
                return a;
            }
        }
        return 0;
    }
};
graphic ss;
int main(){
    int t,n,m,u,v,d;
    cin>>t;
    for(int i = 1 ; i <= t ; ++i){
        ss.init();
        cin>>n>>m;
        printf("Case %d: ",i);
        while (m--){
            scanf("%d%d%d",&u,&v,&d);
            ss.add(u,v,d);
        }
        ss.setST(1,n);
        printf("%lld\n",ss.Dinic());
    }
}

 

转载于:https://www.cnblogs.com/DevilInChina/p/9399406.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值