其他分享
首页 > 其他分享> > 题解 洛谷P2740 [USACO4.2]草地排水Drainage Ditches

题解 洛谷P2740 [USACO4.2]草地排水Drainage Ditches

作者:互联网

题目描述

Link

在农夫约翰的农场上,每逢下雨,贝茜最喜欢的三叶草地就积聚了一潭水。这意味着草地被水淹没了,并且小草要继续生长还要花相当长一段时间。因此,农夫约翰修建了一套排水系统来使贝茜的草地免除被大水淹没的烦恼(不用担心,雨水会流向附近的一条小溪)。作为一名一流的技师,农夫约翰已经在每条排水沟的一端安上了控制器,这样他可以控制流入排水沟的水流量。

农夫约翰知道每一条排水沟每分钟可以流过的水量,和排水系统的准确布局(起点为水潭而终点为小溪的一张网)。需要注意的是,有些时候从一处到另一处不只有一条排水沟。

根据这些信息,计算从水潭排水到小溪的最大流量。对于给出的每条排水沟,雨水只能沿着一个方向流动,注意可能会出现雨水环形流动的情形。

\(0 \le N,M \le 200\) 。

Solution

显然,题目是要求这张图的最大流,我们直接求最大流就可以了。、

注意到 \(N,M \le 200\) ,也就是说, \(\mathcal{O(n^2m)}\) 和 \(\mathcal{O(nm^2)}\) 并没有什么区别。

那么我们直接上 Edmonds-Karp 就可以了,代码如下:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <queue>
using std::queue;
inline int read() {
	int num = 0 ,f = 1; char c = getchar();
	while (!isdigit(c)) f = c == '-' ? -1 : 1 ,c = getchar();
	while (isdigit(c)) num = (num << 1) + (num << 3) + (c ^ 48) ,c = getchar();
	return num * f;
}
inline int min(int a ,int b) {return a < b ? a : b;}
const int N = 205;
const int M = 405;
const int INF = 0x3f3f3f3f;
struct Edge {
	int to ,w ,next;
	Edge(int to = 0 ,int w = 0 ,int next = 0) :
		to(to) ,w(w) ,next(next) {}
}G[M]; int head[N] ,cnt;
inline void add(int u ,int v ,int w) {
	G[++cnt] = Edge(v ,w ,head[u]); head[u] = cnt;
	G[++cnt] = Edge(u ,0 ,head[v]); head[v] = cnt;
}
int n ,m ,s ,t ,maxflow , incf[N] ,pre[N]; bool vis[N];
inline bool bfs() {
	memset(vis ,0 ,sizeof(vis));
	queue <int> q;
	incf[s] = INF; vis[s] = true; q.push(s);
	while (!q.empty()) {
		int now = q.front(); q.pop();
		for (int i = head[now]; i ; i = G[i].next)
			if (G[i].w && !vis[G[i].to]) {
				int v = G[i].to;
				vis[v] = true;
				pre[v] = i;
				incf[v] = min(incf[now] ,G[i].w);
				q.push(v);
				if (v == t) return true;
			}
	}
	return false;
}
inline void EK() {
    int now = t;
    while (now != s) {
        int i = pre[now];
        G[i].w -= incf[t];
        G[i ^ 1].w += incf[t];
        now = G[i ^ 1].to;
    }
    maxflow += incf[t];
}
signed main() {
	cnt = 1;
	m = read(); n = read(); s = 1; t = n;
	for (int i = 1;i <= m; i++) {
		int u = read() ,v = read() ,w = read();
		add(u ,v ,w);
	}
	while (bfs()) EK();
	printf("%d\n" ,maxflow);
	return 0;
}

标签:P2740,include,洛谷,int,题解,while,incf,排水沟,now
来源: https://www.cnblogs.com/Dragon-Skies/p/14190346.html