好裸的题.......
两个cpu分别作为源点和汇点, 每个cpu向元件连边, 权值为题目所给的两个值, 如果两个元件之间有关系, 就在这两个元件之间连边, 权值为消耗,这里的边应该是双向边。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define mem(a) memset(a, 0, sizeof(a)) 4 const int maxn = 3e5+5; 5 int head[maxn*2], s, t, num, q[maxn*3], dis[maxn]; 6 struct node 7 { 8 int to, nextt, c; 9 }e[maxn*2]; 10 void init() { 11 mem1(head); 12 num = 0; 13 } 14 void add(int u, int v, int c) { 15 e[num].to = v; e[num].nextt = head[u]; e[num].c = c; head[u] = num++; 16 } 17 int bfs() { 18 int u, v, st = 0, ed = 0; 19 mem(dis); 20 dis[s] = 1; 21 q[ed++] = s; 22 while(st<ed) { 23 u = q[st++]; 24 for(int i = head[u]; ~i; i = e[i].nextt) { 25 v = e[i].to; 26 if(e[i].c&&!dis[v]) { 27 dis[v] = dis[u]+1; 28 if(v == t) 29 return 1; 30 q[ed++] = v; 31 } 32 } 33 } 34 return 0; 35 } 36 int dfs(int u, int limit) { 37 if(u == t) 38 return limit; 39 int cost = 0; 40 for(int i = head[u]; ~i; i = e[i].nextt) { 41 int v = e[i].to; 42 if(e[i].c&&dis[u] == dis[v]-1) { 43 int tmp = dfs(v, min(limit-cost, e[i].c)); 44 if(tmp>0) { 45 e[i].c -= tmp; 46 e[i^1].c += tmp; 47 cost += tmp; 48 if(cost == limit) 49 break; 50 } else { 51 dis[v] = -1; 52 } 53 } 54 } 55 return cost; 56 } 57 int dinic() { 58 int ans = 0; 59 while(bfs()) { 60 ans += dfs(s, inf); 61 } 62 return ans; 63 } 64 int main() 65 { 66 int n, m, x, y, z; 67 while(~scanf("%d%d", &n, &m)) { 68 s = 0, t = n+1; 69 init(); 70 for(int i = 1; i<=n; i++) { 71 scanf("%d%d", &x, &y); 72 add(s, i, x); 73 add(i, s, 0); 74 add(i, t, y); 75 add(t, i, 0); 76 } 77 while(m--) { 78 scanf("%d%d%d", &x, &y, &z); 79 add(x, y, z); 80 add(y, x, z); 81 } 82 printf("%d ", dinic()); 83 } 84 }