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

    1834: [ZJOI2010]network 网络扩容

    Time Limit: 3 Sec  Memory Limit: 64 MB

    Description

    给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。
    求: 
    1、在不扩容的情况下,1到N的最大流; 
    2、将1到N的最大流增加K所需的最小扩容费用。

    Input

    第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。 
    接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。
    N<=1000,M<=5000,K<=10

    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

    Sample Output

    13 19
     
    先跑出最大流,然后在残量网络上加边,每条边的费用为 c, 限制 n 到汇点的流量为k
    跑费用流,流量流过一次就代表要进行扩容
    跑出的费用就是答案
     
     
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <queue>
      6 #define LL long long
      7 
      8 using namespace std;
      9 
     10 const int MAXM = 1e5 + 10;
     11 const int MAXN = 2e3 + 10;
     12 
     13 queue<int> q;
     14 int S, T;
     15 int N, M, K;
     16 LL u, v, c, w;
     17 const LL inf = 1e9;
     18 LL maxflow = 0;
     19 LL sum = 0;
     20 int cnt = 0;
     21 int pre[MAXN];
     22 int flag[MAXN];
     23 int dis[MAXN];
     24 int e[MAXN];
     25 int h[MAXN];
     26 int head[MAXN];
     27 struct edge {
     28     int u, v;
     29     LL w;
     30     LL c;
     31     int next;
     32 } g[5 * MAXM], ed[2 * MAXM];
     33 
     34 inline LL read()
     35 {
     36     LL x = 0, w = 1; char ch = 0;
     37     while(ch < '0' || ch > '9') {
     38         if(ch == '-') {
     39             w = -1;
     40         }
     41         ch = getchar();
     42     }
     43     while(ch >= '0' && ch <= '9') {
     44         x = x * 10 + ch - '0';
     45         ch = getchar();    
     46     }
     47     return x * w;
     48 }
     49 
     50 void addedge(int u, int v, LL w, LL c)
     51 {
     52     g[cnt].v = v;
     53     g[cnt].w = w;
     54     g[cnt].c = c;
     55     g[cnt].next = head[u];
     56     head[u] = cnt++;
     57 }
     58 
     59 bool BFS() 
     60 {
     61     memset(h, -1, sizeof h);
     62     h[S] = 0;
     63     q.push(S);
     64     while(!q.empty()) {
     65         int t = q.front();
     66         q.pop();
     67         for(int j = head[t]; j != -1; j = g[j].next) {
     68             int to = g[j].v;
     69             if(h[to] == -1 && g[j].w) {
     70                 h[to] = h[t] + 1;
     71                 q.push(to);
     72             }
     73         }
     74     }
     75     return h[T] != -1;
     76 }
     77 
     78 LL DFS(int x, LL f)
     79 {
     80     LL used = 0;
     81     if(x == T) {
     82         return f;
     83     }
     84     for(int j = head[x]; j != -1; j = g[j].next) {
     85         int to = g[j].v;
     86         if(h[to] == h[x] + 1 && g[j].w) {
     87             LL w = f - used;
     88             w = DFS(to, min(w, g[j].w));
     89             g[j].w -= w, g[j ^ 1].w += w;
     90             used += w;
     91             if(used == f) {
     92                 break;
     93             }
     94         }
     95     }
     96     if(used == 0) {
     97         h[x] = -1;
     98     }
     99     return used;
    100 }
    101 
    102 void dinic()
    103 {
    104     while(BFS()) {
    105         maxflow += DFS(S, inf);
    106     }
    107 }
    108 
    109 bool SPFA()
    110 {
    111     memset(pre, -1, sizeof pre);
    112     memset(flag, 0, sizeof flag);
    113     memset(dis, -1, sizeof dis);
    114     dis[S] = 0;
    115     q.push(S);
    116     while(!q.empty()) {
    117         int t = q.front();
    118         q.pop();
    119         flag[t] = 0;
    120         for(int j = head[t]; j != -1; j = g[j].next) {
    121             int to = g[j].v;
    122             if(g[j].w && (dis[to] == -1 || dis[to] > (dis[t] + g[j].c))) {
    123                 dis[to] = dis[t] + g[j].c;
    124                 e[to] = j;
    125                 pre[to] = t;
    126                 if(!flag[to]) {
    127                     flag[to] = 1;
    128                     q.push(to);
    129                 }
    130             }
    131         }
    132     }
    133     if(pre[T] == -1) {
    134         return false;
    135     }
    136     LL maxflow = 1e18;
    137     for(int j = T; pre[j] != -1; j = pre[j]) {
    138         maxflow = min(g[e[j]].w, maxflow);
    139     }
    140     for(int j = T; pre[j] != -1; j = pre[j]) {
    141         g[e[j]].w -= maxflow, g[e[j] ^ 1].w += maxflow;
    142     }
    143     sum += maxflow * dis[T];
    144 }
    145 
    146 int main()
    147 {
    148     memset(head, -1, sizeof head);
    149     N = read(), M = read(), K = read();
    150     S = 0, T = N + 1;
    151     for(int i = 1; i <= M; i++) {
    152         u = read(), v = read(), w = read(), c = read();
    153         addedge(u, v, w, 0);
    154         addedge(v, u, 0, 0);
    155         ed[i].u = u, ed[i].v = v, ed[i].w = w, ed[i].c = c;
    156     }
    157     addedge(S, 1, inf, 0);
    158     addedge(1, S, 0, 0);
    159     addedge(N, T, inf, 0);
    160     addedge(T, N, 0, 0);
    161     dinic();
    162     printf("%lld ", maxflow);
    163     for(int i = 1; i <= M; i++) {
    164         addedge(ed[i].u, ed[i].v, K, ed[i].c);
    165         addedge(ed[i].v, ed[i].u, 0, -ed[i].c);
    166     } 
    167     g[2 * M].w = K;
    168     g[2 * M + 1].w = 0;
    169     while(SPFA()) {
    170     }
    171     printf("%lld
    ", sum);
    172     return 0;
    173 }
    174 
    175 
    176 /*
    177 5 8 2
    178 1 2 5 8
    179 2 5 9 9
    180 5 1 6 2
    181 5 1 1 8
    182 1 2 8 7
    183 2 5 4 9
    184 1 2 1 1
    185 1 4 2 1
    186 
    187 */
    View Code
     
  • 相关阅读:
    UVALive 6044(双连通分量的应用)
    hdu 3760(2次bfs求最短路)
    zoj 3370(二分+二分图染色)
    sgu 326(经典网络流构图)
    hdu 4291(矩阵+暴力求循环节)
    uva 11381(神奇的构图、最小费用最大流)
    hdu 4685(匹配+强连通分量)
    hdu 4496(并查集)
    hdu 4722(记忆化搜索)
    Linux安装Nginx使用负载均衡
  • 原文地址:https://www.cnblogs.com/wuenze/p/8638905.html
Copyright © 2011-2022 走看看