【网络流第三弹】HDU 3549——Flow Problem(dinic解法)

来源:点击打开链接

求有向图的网络流,DINIC模板过,稍作修改即可。

DINIC还是非递归版比较好的,省时间。


// 1.设置上限MAXN和MAXN 2.初始化数值src, des, nNode 3.init_adj() & ex_addEdge() 4.dinic()
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#define init_adj() (eid = 0,memset(p, -1, sizeof (p)))
using namespace std;

const int MAXN=1000,MAXM=120000,INF = 0x3fffffff;

struct node {
	int v, next,flw;
} e[MAXM];

int eid, p[MAXN], lv[MAXN],src, des, nNode;


void ex_addEdge(int u, int v, int c1, int c2) {
    e[eid].v = v;
    e[eid].flw = c1;
    e[eid].next = p[u];
    p[u] = eid++;

    e[eid].v = u;
    e[eid].flw = c2;
    e[eid].next = p[v];
    p[v] = eid++;
}

int bfs() {
    static int que[MAXN];
    int i, u, v, c, cur, f = 0, r = 1;
    memset(lv, 0, sizeof (lv));
    lv[src] = 1, *que = src;
    while (f < r) {
        cur = que[f++], f %= MAXN;
        for (i = p[cur]; ~i; i = e[i].next) {
            u = cur, v = e[i].v, c = e[i].flw;
            if (!lv[v] && c) {
                lv[v] = lv[u] + 1;
                que[r++] = v, r %= MAXN;
            }
        }
    }
    return lv[des];
}

int dfs() {
    static int tp[MAXN], stk[MAXN];
    memcpy(tp, p, sizeof (p));
    int cur, top = -1, flow = 0, u, v, i, part, ind;
    while (1) {
        if (top < 0) {
            for (i = tp[v = src]; ~i; i = e[i].next)
                if (e[i].flw && lv[e[i].v] == 2)
                    break;
            if (i == -1)
                break;
            stk[++top] = tp[src] = i;
        }
        if (e[cur = stk[top]].v != des) {
            u = e[cur].v;
            for (i = tp[u]; ~i; i = e[i].next)
                if (e[i].flw && lv[u] + 1 == lv[e[i].v])
                    break;
            if (~i)
                stk[++top] = tp[u] = i;
            else
                lv[u] = INF, --top;
        } else {
            for (part = INF, i = 0; i <= top; i++)
                if (e[stk[i]].flw < part)
                    part = e[stk[ind = i]].flw;
            flow += part;
            for (i = 0; i <= top; i++)
                e[stk[i]].flw -= part, e[stk[i]^1].flw += part;
            top = --ind;
        }
    }
    return flow;
}

int dinic() {
    int ans = 0, t;
    while (bfs())
        while (t = dfs())
            ans += t;
    return ans;
}

int main()
{
	int testcase;
	int v,w,flow,res,point,road;
	cin>>testcase;
	for(int i=1;i<=testcase;i++)
	{
		init_adj();
		cin>>point>>road;
		src=1;
		des=point;
		nNode=point;
		for(int t=1;t<=road;t++)
		{
			cin>>v>>w>>flow;
			ex_addEdge(v,w,flow,0);
		}
		
		
		res=dinic();
		cout<<"Case "<<i<<": "<<res<<endl;
		
		
		
	}
	
	
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值