zoukankan      html  css  js  c++  java
  • bzoj1834 [ZJOI2010]network 网络扩容

      第一问跑最大流,第二问新建一条边连接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 }
  • 相关阅读:
    BOI 2002 双调路径
    BOI'98 DAY 2 TASK 1 CONFERENCE CALL Dijkstra/Dijkstra+priority_queue/SPFA
    USACO 2013 November Contest, Silver Problem 2. Crowded Cows 单调队列
    BOI 2003 Problem. Spaceship
    USACO 2006 November Contest Problem. Road Blocks SPFA
    CEOI 2004 Trial session Problem. Journey DFS
    USACO 2015 January Contest, Silver Problem 2. Cow Routing Dijkstra
    LG P1233 木棍加工 动态规划,Dilworth
    LG P1020 导弹拦截 Dilworth
    USACO 2007 February Contest, Silver Problem 3. Silver Cow Party SPFA
  • 原文地址:https://www.cnblogs.com/fzmh/p/5406603.html
Copyright © 2011-2022 走看看