上下界费用流比较无脑,提供一种更巧妙的费用流,无需上下界。
1 #include <cstdio> 2 #include <algorithm> 3 #include <queue> 4 #include <cstring> 5 6 const int N = 1610, M = 1000010, INF = 0x3f3f3f3f; 7 8 struct Edge { 9 int nex, v, c, len; 10 }edge[M << 1]; int top = 1; 11 12 int e[N], d[N], vis[N], pre[N], flow[N]; 13 std::queue<int> Q; 14 15 inline void add(int x, int y, int z, int w) { 16 top++; 17 edge[top].v = y; 18 edge[top].c = z; 19 edge[top].len = w; 20 edge[top].nex = e[x]; 21 e[x] = top; 22 23 top++; 24 edge[top].v = x; 25 edge[top].c = 0; 26 edge[top].len = -w; 27 edge[top].nex = e[y]; 28 e[y] = top; 29 return; 30 } 31 32 inline bool SPFA(int s, int t) { 33 memset(d, 0x3f, sizeof(d)); 34 d[s] = 0; 35 flow[s] = INF; 36 vis[s] = 1; 37 Q.push(s); 38 while(!Q.empty()) { 39 int x = Q.front(); 40 Q.pop(); 41 vis[x] = 0; 42 for(int i = e[x]; i; i = edge[i].nex) { 43 int y = edge[i].v; 44 if(edge[i].c && d[y] > d[x] + edge[i].len) { 45 d[y] = d[x] + edge[i].len; 46 pre[y] = i; 47 flow[y] = std::min(flow[x], edge[i].c); 48 if(!vis[y]) { 49 vis[y] = 1; 50 Q.push(y); 51 } 52 } 53 } 54 } 55 return d[t] < INF; 56 } 57 58 inline void update(int s, int t) { 59 int temp = flow[t]; 60 while(t != s) { 61 int i = pre[t]; 62 edge[i].c -= temp; 63 edge[i ^ 1].c += temp; 64 t = edge[i ^ 1].v; 65 } 66 return; 67 } 68 69 inline int solve(int s, int t, int &cost) { 70 int ans = 0; 71 cost = 0; 72 while(SPFA(s, t)) { 73 ans += flow[t]; 74 cost += flow[t] * d[t]; 75 update(s, t); 76 } 77 return ans; 78 } 79 80 int main() { 81 int n, m; 82 scanf("%d%d", &n, &m); 83 int s = n * 2 + 1; 84 int t = s + 1, S = s + 3, T = s + 4, O = s + 5; 85 for(int i = 1, x; i <= n; i++) { 86 scanf("%d", &x); 87 add(O, i, 1, x); 88 add(i + n, O, INF, 0); 89 // add(i, i + n, 1, 0); 90 add(S, i + n, 1, 0); 91 add(i, T, 1, 0); 92 add(i + n, t, 1, 0); 93 } 94 add(s, O, 1, 0); 95 for(int i = 1, x, y, z; i <= m; i++) { 96 scanf("%d%d%d", &x, &y, &z); 97 if(x > y) { 98 std::swap(x, y); 99 } 100 add(x + n, y, INF, z); 101 } 102 add(t, s, INF, 0); 103 104 int ans; 105 solve(S, T, ans); 106 printf("%d", ans); 107 return 0; 108 }