Poj1273 Drainage Ditches 网络流怎么流?

题目背景

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

题目描述

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

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

输入格式

第1行: 两个用空格分开的整数N (0 <= N <= 200) 和 M (2 <= M <= 200)。N是农夫John已经挖好的排水沟的数量,M是排水沟交叉点的数量。交点1是水潭,交点M是小溪。

第二行到第N+1行: 每行有三个整数,Si, Ei, 和 Ci。Si 和 Ei (1 <= Si, Ei <= M) 指明排水沟两端的交点,雨水从Si 流向Ei。Ci (0 <= Ci <= 10,000,000)是这条排水沟的最大容量。

输出格式

输出一个整数,即排水的最大流量。

思路

有水有图有流量,网络流即可,直接上模板。还学会了一个奇妙的初始化方式,对一个struct的二维数组,memset不能用,自己写for循环又太麻烦,直接使用一个新的对象swap存储元素即可。

vector< vector<edge> >(MAX).swap(G);
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

#define MAX 205
#define inf 1e9
#define ll int
#define p pair


struct edge {
	ll to, cap, rev; edge(ll a = 0, ll b = 0, ll c = 0) { to = a, cap = b, rev = c; }
};
vector< vector<edge> >G(MAX);
ll level[MAX], vis[MAX], n, m;

void addEdge(ll from, ll to, ll cap) {
	G[from].push_back(edge( to, cap, G[to].size() ));
	G[to].push_back(edge( from, 0, G[from].size() - 1 ));//反向边
}

void bfs(ll s = 1) {
	memset(level, -1, sizeof(level));
	queue<ll> q; level[s] = 0; q.push(s);
	while (!q.empty()) {
		ll id = q.front(); q.pop();
		for (unsigned i = 0; i < G[id].size(); i++) {
			edge & e = G[id][i];
			if (e.cap > 0 && level[e.to] < 0) {
				level[e.to] = level[id] + 1;
				q.push(e.to);
			}
		}
	}
}

ll dfs(ll v, ll t, ll f) {
	if (v == t)return f;
	for (ll & i = vis[v]; i < G[v].size(); i++) {
		edge & e = G[v][i];
		if (e.cap > 0 && level[v] < level[e.to]) {
			ll d = dfs(e.to, t, min(e.cap, f));
			if (d > 0) {
				G[v][i].cap -= d;
				G[e.to][e.rev].cap += d;
				return d;
			}
		}
	}
	return 0;
}

ll dinic(ll s, ll t) {
	ll flow = 0, f = 0;
	while (true) {
		bfs(s);
		if (level[t] < 0) return flow;
		memset(vis, 0, sizeof(vis));
		while ((f = dfs(s, t, inf)) > 0) flow += f;
	}
}

int main() {
	while (cin >> n >> m) {
		for (ll i = 1; i <= n; i++) {
			ll a, b, c; cin >> a >> b >> c;
			addEdge(a, b, c);
		}
		cout << dinic(1, m) << endl;
		vector< vector<edge> >(MAX).swap(G);
	}
}

你可能感兴趣的:(ACM图论/网络流)