码迷,mamicode.com
首页 > Web开发 > 详细

bzoj1834 [ZJOI2010]network 网络扩容

时间:2016-04-19 06:17:13      阅读:279      评论:0      收藏:0      [点我收藏+]

标签:

  第一问跑最大流,第二问新建一条边连接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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!