1. 程式人生 > >洛谷P2469 星際競速

洛谷P2469 星際競速

update con () memset spfa spa pla ont scanf

上下界費用流比較無腦,提供一種更巧妙的費用流,無需上下界。

技術分享圖片

技術分享圖片
  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 }
上下界費用流AC代碼

洛谷P2469 星際競速