标签:
第一问跑最大流,第二问新建一条边连接0和1,流量为上第一问的答案+k,费用为0,接下来图中每条边拆成两条边,第一条容量为C费用为0,第二条容量无穷费用为W,再跑一遍费用流即可。
代码
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<iostream> 5 #include<set> 6 #include<queue> 7 #define mp make_pair 8 #define inf 0x37373737 9 #define N 30050 10 #define M 30050 11 using namespace std; 12 struct Dinic { 13 int s, t, n, pre[N], cur[N], h[N], level[N], sign, q[N]; 14 int cap[M], to[M], ne[M], flow, e; 15 void liu(int u, int v, int w) { 16 to[e] = v, ne[e] = h[u], cap[e] = w; 17 h[u] = e++; 18 } 19 void link(int u, int v, int w) { 20 liu(u, v, w); 21 liu(v, u, 0); 22 } 23 void init(int n) { 24 for (int i = 0; i <= n; ++i) 25 h[i] = -1; 26 e = 0; 27 } 28 bool bfs() { 29 int L = 0, R = 0; 30 fill(level, level + n, -1); 31 sign = q[R++] = t; 32 level[t] = 0; 33 while (L < R && level[s] == -1) { 34 int c = q[L++]; 35 for (int k = h[c]; ~k; k = ne[k]) { 36 if (cap[k ^ 1] > 0 && level[to[k]] == -1) 37 level[to[k]] = level[c] + 1, q[R++] = to[k]; 38 } 39 } 40 return ~level[s]; 41 } 42 void push() { 43 int pl = inf, p, k; 44 for (p = t; p != s; p = to[k ^ 1]) { 45 k = pre[p]; 46 pl = min(pl, cap[k]); 47 } 48 for (p = t; p != s; p = to[k ^ 1]) { 49 k = pre[p]; 50 cap[k] -= pl; 51 cap[k ^ 1] += pl; 52 if (cap[k] == 0) 53 sign = to[k ^ 1]; 54 } 55 flow += pl; 56 } 57 void dfs(int c) { 58 if (c == t) 59 push(); 60 else { 61 for (int &k = cur[c]; ~k; k = ne[k]) 62 if (cap[k] > 0 && level[to[k]] + 1 == level[c]) { 63 pre[to[k]] = k; 64 dfs(to[k]); 65 if (level[sign] > level[c]) 66 return; 67 sign = t; 68 } 69 level[c] = -1; 70 } 71 } 72 int run(int _s, int _t, int _n) { 73 s = _s, t = _t, n = _n; 74 flow = 0; 75 while (bfs()) { 76 for (int i = 0; i < n; ++i) 77 cur[i] = h[i]; 78 dfs(s); 79 } 80 return flow; 81 } 82 } mf; 83 84 85 struct MCMF{ 86 int h[N] , dis[N] , ing[N] , pre[N] , s , t , n; 87 int to[M] , ne[M] , cap[M] , cost[M] , e; 88 void ini(){ 89 fill(h,h+N,-1); 90 e = 0; 91 } 92 void liu(int u,int v,int c,int w){ 93 to[e] = v , ne[e] = h[u] , cap[e] = c , cost[e] = w; 94 h[u] = e++; 95 } 96 void link(int u,int v,int c,int w){ 97 liu(u,v,c,w); 98 liu(v,u,0,-w); 99 } 100 bool spfa(){ 101 queue<int> Q; 102 fill(ing,ing+n,0); 103 fill(pre,pre+n,-1); 104 fill(dis,dis+n,inf); 105 ing[s] = true , dis[s] = 0; 106 Q.push(s); 107 while(!Q.empty()){ 108 int c = Q.front();Q.pop();ing[c] = false; 109 for(int k=h[c];~k;k=ne[k]){ 110 int v = to[k]; 111 if(cap[k] <= 0) continue; 112 if(dis[c] + cost[k] < dis[v]){ 113 dis[v] = dis[c] + cost[k]; 114 pre[v] = k; 115 if(!ing[v]) Q.push(v) , ing[v] = true; 116 } 117 } 118 } 119 return dis[t] != inf; 120 } 121 int flow , mincost; 122 pair<int,int> run(int _s,int _t,int _n){ 123 s = _s , t = _t , n = _n; 124 flow = mincost = 0; 125 while(spfa()){ 126 int pl = inf , p , k; 127 for(p=t;p!=s;p=to[k^1]){ 128 k = pre[p]; 129 pl = min(pl,cap[k]); 130 } 131 for(p=t;p!=s;p=to[k^1]){ 132 k = pre[p]; 133 cap[k] -= pl; 134 cap[k^1] += pl; 135 } 136 mincost += pl * dis[t]; 137 flow += pl; 138 } 139 return mp(flow,mincost); 140 } 141 }; 142 MCMF mcmf; 143 144 int n,m,k,i,a,b,c,d,flow,cost; 145 int main() 146 { 147 scanf("%d%d%d",&n,&m,&k); 148 mf.init(n+1); 149 mcmf.ini(); 150 for (i=1;i<=m;i++) 151 { 152 scanf("%d%d%d%d",&a,&b,&c,&d); 153 mf.link(a,b,c); 154 mcmf.link(a,b,c,0); 155 mcmf.link(a,b,10000,d); 156 } 157 flow=mf.run(1,n,n+1); 158 mcmf.link(0,1,flow+k,0); 159 printf("%d %d",flow,mcmf.run(0,n,n+1).second); 160 }
bzoj1834 [ZJOI2010]network 网络扩容
标签:
原文地址:http://www.cnblogs.com/fzmh/p/5406603.html