uva 10330 最大流

时间:2022-03-30 17:05:01

拆点  将节点 i 的容量拆成从 i 到 i+n 的边的容量 套用最大流模板 ac

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <sstream>
#include <string>
#include <cstring>
#include <algorithm>
#include <iostream>
#define maxn 210
#define INF 0x7fffffff
#define inf 10000000
#define MOD 1000000007
#define ull unsigned long long
#define ll long long
using namespace std; int n, cap[maxn][maxn], a[maxn], m, flow[maxn][maxn], p[maxn]; int maxflow()
{
queue<int> q;
int f = 0;
memset(flow, 0, sizeof(flow));
while(true)
{
memset(a, 0, sizeof(a));
a[0] = inf;
q.push(0);
while(!q.empty())
{
int u = q.front();
q.pop();
for(int i = 1; i <= n; ++ i)
{
if(!a[i] && cap[u][i] > flow[u][i])
{
p[i] = u;
q.push(i);
a[i] = min(a[u], cap[u][i]-flow[u][i]);
}
}
}
if(!a[n]) break;
for(int i = n; i != 0; i = p[i])
{
flow[p[i]][i] += a[n];
flow[i][p[i]] -= a[n];
}
f += a[n];
}
return f;
} int main()
{
while(scanf("%d", &n) == 1)
{
memset(cap, 0, sizeof(cap));
for(int i = 1; i <= n; ++ i)
{
int temp;
scanf("%d", &temp);
cap[i][i+n] = temp;
}
scanf("%d", &m);
for(int i = 0; i < m; ++ i)
{
int x, y, c;
scanf("%d%d%d", &x, &y, &c);
cap[x+n][y] = c;
}
int a, b;
scanf("%d%d", &a, &b);
for(int i = 0; i < a; ++ i)
{
int x;
scanf("%d", &x);
cap[0][x] = inf;
}
for(int i = 0; i < b; ++ i)
{
int x;
scanf("%d", &x);
cap[x+n][2*n+1] = inf;
}
n = n*2+1;
printf("%d\n", maxflow());
}
return 0;
}