题目大意:发电厂要求把电传输到另一个城市,有N个转换器和发电厂和城市构成了一幅图,每个转换器都有个容量,每条连线之间都有权值,边是有向边
解题思路:将点拆分成变,边的权值为点的容量,2*i表示该点的入点,2*i^1表示该点的出点,然后再构成图即可
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define maxn 220
#define maxm 81000
#define INF 0x3f3f3f3f
int u[maxm],v[maxm],next[maxm],flow[maxm];
int head[maxn],d[maxn],e,N,q[maxm];
void add(int a, int b, int len) {
u[e] = a;
v[e] = b;
flow[e] = len;
next[e] = head[a];
head[a] = e;
e++;
}
void init() {
memset(head,-1,sizeof(head));
e = 0;
int M,D,B,w,st,ed;
for(int i = 1; i <= N; i++) {
scanf("%d",&w);
add(2*i,2*i^1,w);
add(2*i^1,2*i,0);
}
scanf("%d",&M);
for(int i = 0; i < M; i++) {
scanf("%d%d%d",&st,&ed,&w);
add(st*2^1,2*ed,w);
add(2*ed,st*2^1,0);
}
scanf("%d%d",&B,&D);
for(int i = 0; i < B; i++) {
scanf("%d",&w);
add(0,2*w,INF);
add(2*w,0,0);
}
for(int i = 0; i < D; i++) {
scanf("%d",&w);
add(2*w^1,1,INF);
add(1,2*w^1,0);
}
}
int bfs() {
memset(d,-1,sizeof(d));
d[0] = 0;
int rear = 0;
q[rear++] = 0;
for(int i = 0; i < rear; i++)
for(int j = head[q[i]]; j != -1; j = next[j]) {
if(d[v[j]] == -1 && flow[j]) {
d[v[j]] = d[q[i]] + 1;
if(v[j] == 1)
return 1;
q[rear++] = v[j];
}
}
return 0;
}
int dfs(int cur,int a) {
if(cur == 1)
return a;
int i;
for(i = head[cur]; i != -1; i = next[i]) {
if(d[v[i]] == d[cur] + 1 && flow[i])
if(int t = dfs(v[i],a < flow[i] ?a:flow[i])) {
flow[i] -= t;
flow[i^1] += t;
return t;
}
}
if(i == -1)
d[cur] = -1;
return 0;
}
int EK() {
int ans = 0,t;
while(bfs()) {
while(t = dfs(0,INF))
ans += t;
}
return ans;
}
int main() {
while(scanf("%d",&N) != EOF) {
init();
int ans = EK();
printf("%d\n",ans);
}
return 0;
}