zoukankan      html  css  js  c++  java
  • 【费用流】bzoj1834: [ZJOI2010]network 网络扩容

    还是稍微记一下这个拆点模型吧

    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的答案。


    题目分析

    这里只考虑第二问:第一眼看上去像是二分或者最小费用可行流。然而在残量网络里将源点拆为$S$和$S‘$再连$(S,S',K,0)$的边来限制图中新增的费用是一种更好的模型。

    以后再遇到个数限制时候,要及时想到 拆点 的这一类处理方式。

     1 #include<bits/stdc++.h>
     2 //const int maxn = 1035;
     3 const int maxm = 20035;
     4 const int maxNode = 1035;
     5 const int INF = 2e9;
     6 
     7 struct Edge
     8 {
     9     int u,v,f,c,cst;
    10     Edge(int a=0, int b=0, int c=0, int d=0, int e=0):u(a),v(b),f(c),c(d),cst(e) {}
    11 }edges[maxm],sv[maxm];
    12 int n,m,K,ans1,ans2,S,T,SS;
    13 int edgeTot,head[maxNode],nxt[maxm],bck[maxNode],cst[maxNode],flw[maxNode];
    14 bool inq[maxNode];
    15 
    16 int read()
    17 {
    18     char ch = getchar();
    19     int num = 0, fl = 1;
    20     for (; !isdigit(ch); ch=getchar())
    21         if (ch=='-') fl = -1;
    22     for (; isdigit(ch); ch=getchar())
    23         num = (num<<1)+(num<<3)+ch-48;
    24     return num*fl;
    25 }
    26 void addedge(int u, int v, int c, int cst)
    27 {
    28     edges[edgeTot] = Edge(u, v, 0, c,  cst), nxt[edgeTot] = head[u], head[u] = edgeTot, ++edgeTot;
    29     edges[edgeTot] = Edge(v, u, 0, 0, -cst), nxt[edgeTot] = head[v], head[v] = edgeTot, ++edgeTot;
    30 }
    31 std::pair<int, int> maxFlow()
    32 {
    33     int flow = 0, cost = 0;
    34     for (;;)
    35     {
    36         std::queue<int> q;
    37         memset(bck, 0, sizeof bck);
    38         memset(flw, 0, sizeof flw);
    39         memset(cst, 0x3f3f3f3f, sizeof cst);
    40         q.push(S), cst[S] = 0, flw[S] = INF;
    41         for (int tmp; q.size(); )
    42         {
    43             tmp = q.front(), q.pop(), inq[tmp] = 0;
    44             for (int i=head[tmp]; i!=-1; i=nxt[i])
    45             {
    46                 int v = edges[i].v;
    47                 if (cst[v] > cst[tmp]+edges[i].cst&&edges[i].f < edges[i].c){
    48                     cst[v] = cst[tmp]+edges[i].cst, bck[v] = i;
    49                     flw[v] = std::min(flw[tmp], edges[i].c-edges[i].f);
    50                     if (!inq[v]) q.push(v), inq[v] = 1;
    51                 }
    52             }
    53         }
    54         if (!flw[T]) break;
    55         for (int i=T; i!=S; i=edges[bck[i]].u)
    56             edges[bck[i]].f += flw[T], edges[bck[i]^1].f -= flw[T];
    57         flow += flw[T], cost += flw[T]*cst[T];
    58     }
    59     return std::make_pair(flow, cost);
    60 }
    61 int main()
    62 {
    63     memset(head, -1, sizeof head);
    64     n = read(), m = read(), K = read();
    65     for (int i=1; i<=m; i++)
    66     {
    67         int u = read(), v = read(), c = read(), cst = read();
    68         sv[i] = Edge(u, v, 0, c, cst), addedge(u, v, c, 0);
    69     }
    70     SS = 0, S = 1, T = n;
    71     ans1 = maxFlow().first;
    72     std::swap(S, SS);
    73     addedge(S, SS, K, 0);
    74     for (int i=1; i<=m; i++)
    75         addedge(sv[i].u, sv[i].v, INF, sv[i].cst);
    76     ans2 = maxFlow().second;
    77     printf("%d %d
    ",ans1,ans2);
    78     return 0;
    79 }

    END

  • 相关阅读:
    jvm gc 日志详细信息的输出(一)
    带宽与数据传输速率
    功率半导体器件
    超链接标签a样式生效,取消下划线,文字垂直(上下)居中
    防范诈骗
    去掉table中的空隙
    html中使用js实现内容过长时部分
    背景色透明度设置
    jQuery给标签写入内容
    多个div居中显示
  • 原文地址:https://www.cnblogs.com/antiquality/p/10486165.html
Copyright © 2011-2022 走看看