UVA820 因特网带宽 Internet Bandwidth

题意

最大流模板。多组数据。

做法

想学习网络流的可以看我的博客:link。持续更新。

套一个 Dinic 板子即可。注意本题边是双向的。

同时建议加上当前弧优化,复杂度 O(n2m)O(n^2m)。注意要更改反向边的残留流量,使用链式前向星存图,第 ii 条边的反向边就是 i1i \oplus 1,即 ii 异或 11

#include <bits/stdc++.h>
using namespace std;

#define int long long

const int N = 2e4 + 5;

int now = 0, n, m, s, t;

int h[N], e[N], ne[N], c[N], idx;

void add(int u, int v, int w)
{
	e[idx] = v, c[idx] = w, ne[idx] = h[u], h[u] = idx++;
	e[idx] = u, c[idx] = w, ne[idx] = h[v], h[v] = idx++; 
}

int cur[N], d[N];

int bfs()
{
	for (int i = 0; i < N; i++) d[i] = -1;
	cur[s] = h[s], d[s] = 0;
	queue<int> q;
	q.push(s);
	while (q.size())
	{
		int u = q.front();
		q.pop();
		for (int i = h[u]; ~i; i = ne[i])
		{
			int j = e[i];
			if (d[j] == -1 && c[i] > 0)
			{
				d[j] = d[u] + 1;
				cur[j] = h[j];
				q.push(j);
				if (j == t) return 1;
			}
		}
	}
	return 0;
}

int dfs(int u, int lim)
{
	if (u == t) return lim;
	int res = 0;
	for (int i = cur[u]; ~i && res < lim; i = ne[i])
	{
		cur[u] = i;
		int j = e[i];
		if (d[j] == d[u] + 1 && c[i] > 0)
		{
			int k = dfs(j, min(c[i], lim - res));
			if (k == 0) d[j] = -1;
			res += k;
			c[i] -= k;
			c[i ^ 1] += k;
		}
	}
	return res;
}

int dinic()
{
	int res = 0;
	while (bfs())
	{
		int f = 0;
		while (f = dfs(s, (int)1e18)) res += f;
	}
	return res;
}

signed main()
{
	while (scanf("%lld", &n) && n)
	{
		memset(h, -1, sizeof h);
		memset(ne, 0, sizeof ne);
		idx = 0;
		now++;
		scanf("%lld%lld%lld", &s, &t, &m);
		for (int i = 1; i <= m; i++)
		{
			int u, v, w;
			scanf("%lld%lld%lld", &u, &v, &w);
			add(u, v, w);
		}
		printf("Network %lld\n", now);
		printf("The bandwidth is %lld.\n", dinic());
		printf("\n");
	}
	return 0;
}
posted @   HappyBobb  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示