BZOJ1834: [ZJOI2010]network 网络扩容
1834: [ZJOI2010]network 网络扩容
Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 3490 Solved: 1827
[Submit][Status][Discuss]
Description
给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求:
1、 在不扩容的情况下,1到N的最大流;
2、 将1到N的最大流增加K所需的最小扩容费用。
Input
输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。
接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。
Output
输出文件一行包含两个整数,分别表示问题1和问题2的答案。
Sample Input
5 8 2
1 2 5 8
2 5 9 9
5 1 6 2
5 1 1 8
1 2 8 7
2 5 4 9
1 2 1 1
1 4 2 1
1 2 5 8
2 5 9 9
5 1 6 2
5 1 1 8
1 2 8 7
2 5 4 9
1 2 1 1
1 4 2 1
Sample Output
13 19
30%的数据中,N<=100
100%的数据中,N<=1000,M<=5000,K<=10
30%的数据中,N<=100
100%的数据中,N<=1000,M<=5000,K<=10
HINT
Source
先求最大流,然后在残余网络上建图,对于原有的每一条边建一条容量INF费用c的边,新源点S指向1容量k费用0即可
莫名其妙被Longlong传参int卡了?
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 #include <vector> 8 #define min(a, b) ((a) < (b) ? (a) : (b)) 9 #define max(a, b) ((a) > (b) ? (a) : (b)) 10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a)) 11 inline void swap(int &a, int &b) 12 { 13 int tmp = a;a = b;b = tmp; 14 } 15 inline void read(int &x) 16 { 17 x = 0;char ch = getchar(), c = ch; 18 while(ch < '0' || ch > '9') c = ch, ch = getchar(); 19 while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar(); 20 if(c == '-') x = -x; 21 } 22 23 const int INF = 0x3f3f3f3f; 24 const int MAXN = 100000 + 10; 25 const int MAXM = 500000 + 10; 26 const int MAXK = 10 + 2; 27 28 struct Edge 29 { 30 int u,v,nxt,w,c; 31 Edge(int _u, int _v, int _nxt, int _w, int _c){u = _u;v = _v;nxt = _nxt;w = _w;c = _c;} 32 Edge(){} 33 }edge[MAXM << 1]; 34 35 int cnt = 1, head[MAXN], from[MAXN]; 36 bool b[MAXN]; 37 int S, T; 38 int d[MAXN], ans; 39 int q[MAXN << 1]; 40 int n,m,k; 41 42 inline void insert(int u, int v, int w, int c) 43 { 44 edge[++cnt] = Edge(u, v, head[u], w, c); 45 head[u] = cnt; 46 edge[++cnt] = Edge(v, u, head[v], 0, -c); 47 head[v] = cnt; 48 } 49 50 bool spfa() 51 { 52 memset(d, 0x3f, sizeof(d)); 53 int he = 0, ta = 1; 54 d[S] = 0, b[S] = 1, q[he] = S; 55 while(he != ta) 56 { 57 int now = q[he ++]; 58 if(he > n) he = 0; 59 for(int pos = head[now];pos;pos = edge[pos].nxt) 60 if(edge[pos].w && d[edge[pos].v] > d[now] + edge[pos].c) 61 { 62 d[edge[pos].v] = d[now] + edge[pos].c; 63 from[edge[pos].v] = pos; 64 if(!b[edge[pos].v]) 65 { 66 b[edge[pos].v]=1; 67 q[ta ++] = edge[pos].v; 68 if(ta > n)ta = 0; 69 } 70 } 71 b[now] = 0; 72 } 73 if(d[T] == INF)return 0; 74 return 1; 75 } 76 77 void flow() 78 { 79 int x = INF; 80 for(int i = from[T];i;i = from[edge[i].u]) 81 x = min(x, edge[i].w); 82 for(int i = from[T];i;i = from[edge[i].u]) 83 { 84 edge[i].w -= x; 85 edge[i^1].w += x; 86 ans += edge[i].c * x; 87 } 88 } 89 90 void mcmf() 91 { 92 while(spfa()) flow(); 93 } 94 95 int h[MAXN << 1], qq[MAXN]; 96 97 bool bfs() 98 { 99 int he = 0, ta = 1; 100 memset(h, -1, sizeof(h)); 101 h[S] = 0;qq[he] = S; 102 while(he < ta) 103 { 104 int now = qq[he ++]; 105 for(int pos = head[now];pos;pos = edge[pos].nxt) 106 { 107 int v = edge[pos].v; 108 if(h[v] == -1 && edge[pos].w) 109 { 110 h[v] = h[now] + 1; 111 qq[ta ++] = v; 112 } 113 } 114 } 115 return h[T] != -1; 116 } 117 int dfs(int x, int f) 118 { 119 if(x == T) return f; 120 int w, used = 0; 121 for(int pos = head[x];pos;pos = edge[pos].nxt) 122 { 123 int v = edge[pos].v; 124 if(h[v] == h[x] + 1) 125 { 126 w = dfs(v, min(f - used, edge[pos].w)); 127 edge[pos].w -= w; 128 edge[pos ^ 1].w += w; 129 used += w; 130 if(used == f) return f; 131 } 132 } 133 if(!used) h[x] = -1; 134 return used; 135 } 136 void dinic() 137 { 138 while(bfs()) ans += dfs(S, INF); 139 } 140 141 int u[MAXM], v[MAXM], w[MAXM], c[MAXM]; 142 143 int main() 144 { 145 read(n), read(m), read(k); 146 for(register int i = 1;i <= m;++ i) 147 { 148 read(u[i]), read(v[i]), read(w[i]), read(c[i]); 149 insert(u[i], v[i], w[i], 0); 150 } 151 S = 1, T = n; 152 dinic(); 153 printf("%d ", ans); 154 ans = 0; 155 for(register int i = 1;i <= m;++ i) 156 insert(u[i], v[i], INF, c[i]); 157 S = 1100; 158 insert(S, 1, k, 0); 159 mcmf(); 160 printf("%d", ans); 161 return 0; 162 }