UVA 10330 Power Transmission 网络流 拆点+多源点多汇点

来源:互联网 发布:淘宝入店来源直接访问 编辑:程序博客网 时间:2024/05/16 17:05

题意:一张有向图由n个点构成,每个点都有一个容量限制,然后给出多个源点和多个汇点。

经典的模型,拆点,构造超级源点和超级汇点,然后用最大流算法即可。

注意要小心构造图。

代码:

/**  Author:      illuz <iilluzen[at]gmail.com>*  Blog:        http://blog.csdn.net/hcbbt*  File:        uva10330.cpp*  Create Date: 2013-12-06 15:51:52*  Descripton:  拆点, max flow */#include <cstdio>#include <cstring>#include <iostream>#include <queue>#include <algorithm>using namespace std;const int MAXN = 210;const int INF = 0X3C3C3C3C;int mr[MAXN];// 从源点到i的最小残量int p[MAXN];// 更新时i的上流节点int c[MAXN][MAXN], f[MAXN][MAXN];// capitar and flowint maxFlow(int op, int ed, int n)// start, end, num of points{queue<int> q;memset(f, 0, sizeof(f));memset(p, 0, sizeof(p));int F = 0;// total flow// bfswhile (1) {memset(mr, 0, sizeof(mr));q.push(op);mr[op] = INF;// 源点残量while (!q.empty()) {int u = q.front();q.pop();for (int v = 0; v < n; v++) if (!mr[v] && c[u][v] > f[u][v]) {p[v] = u;q.push(v);mr[v] = min(mr[u], c[u][v] - f[u][v]);}}if (mr[ed] == 0) return F;// updatefor (int u = ed; u != op; u = p[u]) {f[u][p[u]] -= mr[ed];f[p[u]][u] += mr[ed];}F += mr[ed];}}int main() {int n, nn, en, b, d, u, v, cast;while (scanf("%d", &n) != EOF) {memset(c, 0, sizeof(c));// 拆点for (int i = 1; i <= n; i++)scanf("%d", &c[i][i + n]);scanf("%d", &en);while (en--) {scanf("%d%d%d", &u, &v, &cast);c[u + n][v] = cast;// 这里也要处理}// 构建超级源点和超级汇点scanf("%d%d", &b, &d);while (b--) {scanf("%d", &u);c[0][u] = INF;}while (d--) {scanf("%d", &u);c[u + n][2 * n + 1] = INF;}printf("%d\n", maxFlow(0, 2 * n + 1, 2 * n + 2));}return 0;}


原创粉丝点击