• 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 }
  • 相关阅读:
    【转载】两军问题与Paxos算法 & 动画讲解Paxos算法
    hdu4611 Balls Rearrangement
    [置顶] github简单使用
    set与map容器
    [置顶] C++为什么是C++而不是++C
    HDU 4616 Game (搜索)、(树形dp)
    Just learn how to use the JNI
    HDU 4611 Balls Rearrangement (数学-思维逻辑题)
    冒泡排序改进
    Python基础
  • 原文地址:https://www.cnblogs.com/fzmh/p/5406603.html
Copyright © 2020-2023  润新知