dinic / 網絡流_ACM模板

網絡流: dinic

題目描述
每當農民約翰的田地下雨,池塘就形成在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;
const int inf = 1 << 30;

struct edge {
	int v, f, nxt;
}e[maxn << 1];

int num, n, m, s, t, g[maxn];
queue<int> que;
int vis[maxn], d[maxn];

void addedge(int u, int v, int val) {
	e[++num].v = v;
	e[num].f = val;
	e[num].nxt = g[u];
	g[u] = num;
	e[++num].v = u;
	e[num].f = 0;
	e[num].nxt = g[v];
	g[v] = num;
}

void bfs() {
	memset(d, 0, sizeof(d));
	while (!que.empty()) que.pop();
	vis[s] = 1, que.push(s);
	while (!que.empty()) {
		int u = que.front(); que.pop();
		for (int i = g[u]; i; i = e[i].nxt) {
			if (e[i].f && !vis[e[i].v]) {
				d[e[i].v] = d[u] + 1;
				vis[e[i].v] = 1;
				que.push(e[i].v);
			}
		}
	}
}

int dfs(int u, int flow) {
	if (u == t)
		return flow;
	else {
		int ans = 0;
		for (int i = g[u]; flow&&i; i = e[i].nxt) {
			if (e[i].f&&d[e[i].v] == d[u] + 1) {
				int dd = dfs(e[i].v, min(e[i].f, flow));
				e[i].f -= dd;
				e[i ^ 1].f += dd;
				flow -= dd;
				ans += dd;
			}
		}
		return ans;
	}
}

int dinic() {
	int ans = 0;
	while (true) {
		memset(vis, 0, sizeof(vis));
		bfs();
		if (!vis[t])
			return ans;
		ans += dfs(s, inf);
	}
}

int main() {
	ios::sync_with_stdio(false);
	while (cin >> m >> n) {
		memset(g, 0, sizeof(g));
		num = 1;
		int x, y, z;
		while (m--) {
			cin >> x >> y >> z;
			addedge(x, y, z);
		}
		s = 1, t = n;
		cout << dinic() << endl;
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章