• BZOJ1834: [ZJOI2010]network 网络扩容


    1834: [ZJOI2010]network 网络扩容

    Time Limit: 3 Sec  Memory Limit: 64 MB
    Submit: 3490  Solved: 1827
    [Submit][Status][Discuss]

    Description

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

    Input

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

    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
    30%的数据中,N<=100
    100%的数据中,N<=1000,M<=5000,K<=10

    HINT

    Source

    先求最大流,然后在残余网络上建图,对于原有的每一条边建一条容量INF费用c的边,新源点S指向1容量k费用0即可

    莫名其妙被Longlong传参int卡了?

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <queue>
      7 #include <vector>
      8 #define min(a, b) ((a) < (b) ? (a) : (b))
      9 #define max(a, b) ((a) > (b) ? (a) : (b))
     10 #define abs(a) ((a) < 0 ? (-1 * (a)) : (a))
     11 inline void swap(int &a, int &b)
     12 {
     13     int tmp = a;a = b;b = tmp;
     14 }
     15 inline void read(int &x)
     16 {
     17     x = 0;char ch = getchar(), c = ch;
     18     while(ch < '0' || ch > '9') c = ch, ch = getchar();
     19     while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
     20     if(c == '-') x = -x;
     21 }
     22 
     23 const int INF = 0x3f3f3f3f;
     24 const int MAXN = 100000 + 10;
     25 const int MAXM = 500000 + 10;
     26 const int MAXK = 10 + 2;
     27 
     28 struct Edge
     29 {
     30     int u,v,nxt,w,c;
     31     Edge(int _u, int _v, int _nxt, int _w, int _c){u = _u;v = _v;nxt = _nxt;w = _w;c = _c;} 
     32     Edge(){}
     33 }edge[MAXM << 1];
     34 
     35 int cnt = 1, head[MAXN], from[MAXN];
     36 bool b[MAXN];
     37 int S, T;
     38 int d[MAXN], ans;
     39 int q[MAXN << 1];
     40 int n,m,k;
     41 
     42 inline void insert(int u, int v, int w, int c)
     43 {
     44     edge[++cnt] = Edge(u, v, head[u], w, c);
     45     head[u] = cnt;
     46     edge[++cnt] = Edge(v, u, head[v], 0, -c);
     47     head[v] = cnt;
     48 }
     49 
     50 bool spfa()
     51 {
     52     memset(d, 0x3f, sizeof(d));
     53     int he = 0, ta = 1;
     54     d[S] = 0, b[S] = 1, q[he] = S;
     55     while(he != ta)
     56     {
     57         int now = q[he ++];
     58         if(he > n) he = 0;
     59         for(int pos = head[now];pos;pos = edge[pos].nxt)
     60             if(edge[pos].w && d[edge[pos].v] > d[now] + edge[pos].c)
     61             {
     62                 d[edge[pos].v] = d[now] + edge[pos].c;
     63                 from[edge[pos].v] = pos;
     64                 if(!b[edge[pos].v])
     65                 {
     66                     b[edge[pos].v]=1;
     67                     q[ta ++] = edge[pos].v;
     68                     if(ta > n)ta = 0;
     69                 } 
     70             }
     71         b[now] = 0; 
     72     }
     73     if(d[T] == INF)return 0;
     74     return 1;
     75 }
     76 
     77 void flow()
     78 {
     79     int x = INF;
     80     for(int i = from[T];i;i = from[edge[i].u])
     81         x = min(x, edge[i].w);
     82     for(int i = from[T];i;i = from[edge[i].u])
     83     {
     84         edge[i].w -= x;
     85         edge[i^1].w += x;
     86         ans += edge[i].c * x;
     87     }
     88 }
     89 
     90 void mcmf()
     91 {
     92     while(spfa()) flow();
     93 }
     94 
     95 int h[MAXN << 1], qq[MAXN];
     96 
     97 bool bfs()
     98 {
     99     int he = 0, ta = 1;
    100     memset(h, -1, sizeof(h));
    101     h[S] = 0;qq[he] = S;
    102     while(he < ta)
    103     {
    104         int now = qq[he ++];
    105         for(int pos = head[now];pos;pos = edge[pos].nxt)
    106         {
    107             int v = edge[pos].v;
    108             if(h[v] == -1 && edge[pos].w)
    109             {
    110                 h[v] = h[now] + 1;
    111                 qq[ta ++] = v;
    112             }
    113         }
    114     }
    115     return h[T] != -1;
    116 }
    117 int dfs(int x, int f)
    118 {
    119     if(x == T) return f;
    120     int w, used = 0;
    121     for(int pos = head[x];pos;pos = edge[pos].nxt)
    122     {
    123         int v = edge[pos].v;
    124         if(h[v] == h[x] + 1)
    125         {
    126             w = dfs(v, min(f - used, edge[pos].w));
    127             edge[pos].w -= w;
    128             edge[pos ^ 1].w += w;
    129             used += w;
    130             if(used == f) return f;
    131         }
    132     }
    133     if(!used) h[x] = -1;
    134     return used;
    135 }
    136 void dinic()
    137 {
    138     while(bfs()) ans += dfs(S, INF);
    139 }
    140 
    141 int u[MAXM], v[MAXM], w[MAXM], c[MAXM];
    142 
    143 int main()
    144 {
    145     read(n), read(m), read(k);
    146     for(register int i = 1;i <= m;++ i)
    147     {
    148         read(u[i]), read(v[i]), read(w[i]), read(c[i]);
    149         insert(u[i], v[i], w[i], 0);
    150     }
    151     S = 1, T = n;
    152     dinic();
    153     printf("%d ", ans);
    154     ans = 0;
    155     for(register int i = 1;i <= m;++ i)
    156         insert(u[i], v[i], INF, c[i]);
    157     S = 1100;
    158     insert(S, 1, k, 0);
    159     mcmf();
    160     printf("%d", ans);
    161     return 0;
    162 } 
    BZOJ1834
  • 相关阅读:
    python 模块特点
    python 对象类型有哪些?
    python 异常处理
    python urllib2查询数据
    哈希表之词频统计
    泛型 队列
    大小端存储
    收藏 去掉 html 标签的perl 小函数
    好玩 多线程 显示
    服务器客户端 之 文件下载
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/8290547.html
Copyright © 2020-2023  润新知