題目: UVa - 10594 - Data Flow
題目說明
給你一個無向圖,兩點之間的邊的容量是 K,每條邊有不同的 cost,現在有大小為 D 的資料,要從起點傳到終點,問把全部資料傳過去的最小 cost 是多少,如果不能全部傳過去則輸出 Impossible. 第一行輸入 N M:總共N個點,編號從 1 ~ N,然後底下有 M 行 有 M 行,每行 u v c:表示點 u 和點 v 之間的 cost 為 c (雙向圖) 最後一行 D K:要傳的資料大小為 D,每個邊的容量為 K
Programming學習筆記: UVa 10594 Data Flow
解題思路 建圖後求 MCMF 即可。
參考解法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 #include <bits/stdc++.h> using namespace std ;#define FOR(i, a, b) for (int i = a; i < b; ++i) #define CLR(c) memset(c, 0, sizeof(c)) typedef long long ll;static auto __ = []{ ios_base::sync_with_stdio(0 ); cin .tie(0 ); cout .tie(0 ); return 0 ; }(); template <typename T>T QPOP (queue <T>& q) { T tmp = q.front(); q.pop(); return tmp; } const int INF = (int )1e9 ;const int MXN = 105 ;vector <int > e[MXN];ll c[MXN][MXN]; ll f[MXN][MXN]; ll cost[MXN][MXN]; ll d[MXN]; int p[MXN];bool inQ[MXN];int S = 1 , T;int N, M, D, K;void addEdge (int u, int v, int Cap = 0 , int Cost = 0 ) { e[u].push_back(v); c[u][v] = Cap; cost[u][v] = Cost; } void init () { T = N; for (auto & v : e) v.clear(); CLR(f); } void read () { int u, v, C; while (M--) { cin >> u >> v >> C; addEdge(u, v, 1 , C); addEdge(v, u, 1 , C); } cin >> D >> K; } bool SPFA () { fill(d, d + MXN, INF); d[S] = 0 ; CLR(inQ); queue <int > q; q.push(S); inQ[S] = true ; while (!q.empty()) { auto u = QPOP(q); inQ[u] = false ; for (auto & v : e[u]) { if (c[u][v] > f[u][v] && d[u] + cost[u][v] < d[v]) { d[v] = d[u] + cost[u][v]; p[v] = u; if (!inQ[v]) q.push(v), inQ[v] = true ; } if (f[v][u] > 0 && d[u] + (-cost[v][u]) < d[v]) { d[v] = d[u] + (-cost[v][u]); p[v] = u; if (!inQ[v]) q.push(v), inQ[v] = true ; } } } return d[T] != INF; } ll augment (int u, int v, ll bottleNeck) { if (v == S) return bottleNeck; bottleNeck = augment(p[u], u, min(c[u][v] - f[u][v], bottleNeck)); f[u][v] += bottleNeck; f[v][u] -= bottleNeck; return bottleNeck; } ll MCMF () { ll mnC = 0 ; while (SPFA()) { mnC += min(K, D) * d[T]; D -= K; if (D <= 0 ) break ; augment(p[T], T, INF); } if (D <= 0 ) return mnC; return -1 ; } void solve () { auto mnC = MCMF(); if (mnC != -1 ) cout << mnC << '\n' ; else cout << "Impossible.\n" ; } int main () { while (cin >> N >> M) { init(); read(); solve(); } }
參考資料 Programming學習筆記: UVa 10594 Data Flow