UVa 10330 - Power Transmission (最大流+拆点)

拆点:在这道题里边学会了拆点的思想。简单说就是对于一个点i,将其拆成两个虚点 i 以及 i',然后从 i 连边到 i' ,容量为所要求(本题为调节器)的容量。而对于两个真实点i和j,本该是i连到j,现在将i‘连到j,容量为原先i到j的容量。

#include <stdio.h>
#include <string.h>
#include <queue>
#define min(a,b) (a)<(b)?(a):(b)
#define max(a,b) (a)>(b)?(a):(b)
#define INF 0x3f3f3f3f
using namespace std;

const int N = 205;

int n, limit, m, A, B, V, sn, tn, line, g[N][N], f[N][N], a[N], p[N];
queue<int>q;

void init() {
    memset(g, 0, sizeof(g));
    for (int i = 1; i <= n; i ++) {
	scanf("%d", &limit);
	g[i][i + n] = limit;
    }
    scanf("%d", &m);
    while (m --) {
	scanf("%d%d%d", &A, &B, &V);
	g[A + n][B] = V;
    }
    scanf("%d%d", &sn, &tn);
    for (int i = 0; i < sn; i ++) {
	scanf("%d", &line);
	g[0][line] = INF;
    }
    for (int i = 0; i < tn; i ++) {
	scanf("%d", &line);
	g[line + n][2 * n + 1] = INF;
    }
}

int solve(int s, int t) {
    init();
    int ans = 0;
    memset(f, 0, sizeof(f));
    while (1) {
	memset(a, 0, sizeof(a));
	a[s] = INF;
	q.push(s);
	while (!q.empty()) {
	    int u = q.front(); q.pop();
	    for (int v = 1; v <= t; v ++) {
		if (!a[v] && g[u][v] > f[u][v]) {
		    p[v] = u; q.push(v);
		    a[v] = min(a[u], g[u][v] - f[u][v]);
		}
	    }
	}
	if (!a[t]) break;
	for (int u = t; u != s; u = p[u]) {
	    f[p[u]][u] += a[t];
	    f[u][p[u]] -= a[t];
	}
	ans += a[t];
    }
    return ans;
}

int main() {
    while (~scanf("%d", &n)) {
	printf("%d\n", solve(0, 2 * n + 1));
    }
    return 0;
}



你可能感兴趣的:(UVa 10330 - Power Transmission (最大流+拆点))