hdu 3667 (拆边 mcmf)
注意题目中 边的容量 <= 5.可以把费用权值 a *f ^2化归成 a * f2, 即第一条边费用为 1 * a, 第二条 为 (4 - 1) * a, 第三条为 (9 - 4) * a。。。。。。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 6 using namespace std; 7 8 const int maxn = 110; 9 const int maxm = 25000; 10 const int inf = 0x3f3f3f3f; 11 const int ww[5] = {1, 3, 5, 7, 9}; 12 13 struct MCMF 14 { 15 struct Edge 16 { 17 int v, c, w, next; 18 }p[maxm << 1]; 19 int e, head[maxn], dis[maxn], pre[maxn], cnt[maxn], sumFlow, n; 20 bool vis[maxn]; 21 void init(int nt) 22 { 23 e = 0; n = nt; 24 memset(head, -1, sizeof(head[0]) * (n + 2)); 25 } 26 void addEdge(int u, int v, int c, int w) 27 { 28 p[e].v = v; p[e].c = c; p[e].w = w; p[e].next = head[u]; head[u] = e++; 29 swap(u, v); 30 p[e].v = v; p[e].c = 0; p[e].w =-w; p[e].next = head[u]; head[u] = e++; 31 } 32 bool spfa(int S, int T) 33 { 34 queue <int> q; 35 for (int i = 0; i <= n; ++i) 36 vis[i] = cnt[i] = 0, pre[i] = -1, dis[i] = inf; 37 vis[S] = 1; dis[S] = 0; 38 q.push(S); 39 while (!q.empty()) 40 { 41 int u = q.front(); q.pop(); 42 vis[u] = 0; 43 for (int i = head[u]; i + 1; i = p[i].next) 44 { 45 int v = p[i].v; 46 if (p[i].c && dis[v] > dis[u] + p[i].w) 47 { 48 dis[v] = dis[u] + p[i].w; 49 pre[v] = i; 50 if (!vis[v]) 51 { 52 q.push(v); 53 vis[v] = 1; 54 if (++cnt[v] > n) return 0; 55 } 56 } 57 } 58 } 59 return dis[T] != inf; 60 } 61 int mcmf(int S, int T) 62 { 63 sumFlow = 0; 64 int minFlow = 0, minCost = 0; 65 while (spfa(S, T)) 66 { 67 minFlow = inf + 1; 68 for (int i = pre[T]; i + 1; i = pre[ p[i ^ 1].v ]) 69 minFlow = min(minFlow, p[i].c); 70 sumFlow += minFlow; 71 for (int i = pre[T]; i + 1; i = pre[ p[i ^ 1].v ]) 72 p[i].c -= minFlow, p[i ^ 1].c += minFlow; 73 minCost += dis[T] * minFlow; 74 } 75 return minCost; 76 } 77 void build(int nt, int mt, int kt) 78 { 79 init(nt); 80 addEdge(0, 1, kt, 0); 81 int u, v, c, w; 82 for (int i = 0; i < mt; ++i) 83 { 84 scanf("%d%d%d%d", &u, &v, &w, &c); 85 for (int j = 0; j < c; ++j) 86 addEdge(u, v, 1, w * ww[j]); 87 } 88 } 89 void solve(int nt, int mt, int kt) 90 { 91 build(nt, mt, kt); 92 int ans = mcmf(0, n); 93 // cout <<"sumFlow = " << sumFlow << " cost = " << ans << endl; 94 if (sumFlow != kt) 95 printf("-1\n"); 96 else 97 printf("%d\n", ans); 98 } 99 }my; 100 101 int main() 102 { 103 int n, m, k; 104 while (~scanf("%d%d%d", &n, &m, &k)) 105 my.solve(n, m, k); 106 return 0; 107 }