模板——EK网络流

网络流: EK网络流

题目描述
每当农民约翰的田地下雨,池塘就形成在Bessie最喜欢的三叶草补丁上。这意味着三叶草被水覆盖了一段时间,需要相当长的时间才能再生。因此,农民约翰已经建立了一套排水沟,使Bessie的苜蓿补丁从来没有覆盖在水中。取而代之的是,水被排入附近的溪流中。作为一名ACE工程师,农民约翰也在每个沟的开始安装了调节器,所以他可以控制水流到沟里的速率。
农场主约翰不仅知道每条沟每分钟能输送多少加仑水,而且知道沟渠的精确布局,这些沟渠从池塘中流入,相互流入,并在一个潜在的复杂网络中流动。
考虑到所有这些信息,确定水可以从池塘中运输到河流中的最大速率。对于任何给定的沟渠,水流只有一个方向,但可能有一种方式,水可以在一个圆中流动。

输入
输入包括几种情况。对于每一种情况,第一行包含两个空间分离的整数,n(0<n<=200)和m(2 <=m <=200)。N是农民约翰挖沟的数量。M是那些沟渠的交叉点。十字路口1是池塘。交叉点M是流。以下n行中的每一个包含三个整数,SI、颖娃和CI。Si和Ei(1<Si,Ei <=m)表示该沟之间的交汇点。水将从这条沟从Si流入颖娃。CI(0<CI=10000000)是水通过沟道的最大速率。

输出
对于每一种情况,输出一个单一的整数,水可以从池塘中排空的最大速率。

样本输入

5,4,1,2,40,1,4,20,2,4,20,2,2,

样本输出

50

const int maxn = 210;
int s, t, n, m, pre[maxn], mp[maxn][maxn];
queue<int> que;
int bfs() {
	int vis[maxn], flow[maxn];
	memset(vis, 0, sizeof(vis));
	memset(flow, -1, sizeof(flow));
	while (!que.empty()) que.pop();
	vis[s] = 1, flow[s] = 1 << 30, pre[s] = s, que.push(s);
	while (!que.empty()) {
		int u = que.front(); que.pop();
		for (int i = 1; i <= n; i++) {
			if (!vis[i] && mp[u][i]) {
				vis[i] = 1;
				flow[i] = min(flow[u], mp[u][i]);
				pre[i] = u;
				que.push(i);
			}
		}
	}
	if (flow[t] == -1)
		return 0;
	return flow[t];
}

int EK() {
	int ans = 0, flow;
	while (flow = bfs()) {
		ans += flow;
		int x = t;
		while (x != s) {
			mp[pre[x]][x] -= flow;
			mp[x][pre[x]] += flow;
			x = pre[x];
		}
	}
	return ans;
}

int main() {
	ios::sync_with_stdio(false);
	int x, y, z;
	while (cin >> m >> n) {
		memset(mp, 0, sizeof(mp));
		for (int i = 0; i < m; i++)
			cin >> x >> y >> z, mp[x][y] += z;
		s = 1, t = n;
		cout << EK() << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值