zoukankan      html  css  js  c++  java
  • 【上下界网络流 费用流】bzoj2055: 80人环游世界

    EK费用流居然写错了……

    Description

        想必大家都看过成龙大哥的《80天环游世界》,里面的紧张刺激的打斗场面一定给你留下了深刻的印象。现在就有这么
        一个80人的团伙,也想来一次环游世界。
        他们打算兵分多路,游遍每一个国家。
        因为他们主要分布在东方,所以他们只朝西方进军。设从东方到西方的每一个国家的编号依次为1...N。假若第i个人的游历路线为P1、P2......Pk(0≤k≤N),则P1<P2<......<Pk。
        众所周知,中国相当美丽,这样在环游世界时就有很多人经过中国。我们用一个正整数Vi来描述一个国家的吸引程度,Vi值越大表示该国家越有吸引力,同时也表示有且仅
    有Vi个人会经过那一个国家。
        为了节省时间,他们打算通过坐飞机来完成环游世界的任务。同时为了省钱,他们希望总的机票费最小。
        明天就要出发了,可是有些人临阵脱逃,最终只剩下了M个人去环游世界。他们想知道最少的总费用,你能告诉他们吗?

    Input

    第一行两个正整数N,M。
    第二行有N个不大于M正整数,分别表示V1,V2......VN。
    接下来有N-1行。第i行有N-i个整数,该行的第j个数表示从第i个国家到第i+j个国家的机票费(如果该值等于-1则表示这两个国家间没有通航)。

    Output

    在第一行输出最少的总费用。

    Sample Input

    6 3
    2 1 3 1 2 1
    2 6 8 5 0
    8 2 4 1
    6 1 0
    4 -1
    4

    Sample Output

    27

    HINT

    1<= N < =100 1<= M <= 79


    题目分析

    这就是一个无源汇最小费用最大流的模型,关于M个人的限制则是把(TT,SS)的边流量设为M

    掌握得还是不够熟练啊

     1 #include<bits/stdc++.h>
     2 const int maxn = 503;
     3 const int maxm = 200035;
     4 const int INF = 2e9;
     5 
     6 struct Edge
     7 {
     8     int u,v,f,c,cst;
     9     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) {}
    10 }edges[maxm];
    11 int n,m,S,T,SS,TT,ans;
    12 int edgeTot,head[maxn],nxt[maxm],bck[maxm],cst[maxn],flw[maxn];
    13 bool inq[maxn<<2];
    14 
    15 void addedge(int u, int v, int c, int cst)
    16 {
    17     edges[edgeTot] = Edge(u, v, 0, c,  cst), nxt[edgeTot] = head[u], head[u] = edgeTot, ++edgeTot;
    18     edges[edgeTot] = Edge(v, u, 0, 0, -cst), nxt[edgeTot] = head[v], head[v] = edgeTot, ++edgeTot;
    19 }
    20 void maxFlow()
    21 {
    22     for (;;)
    23     {
    24         std::queue<int> q;
    25         memset(flw, 0, sizeof flw);
    26         memset(bck, 0, sizeof bck);
    27         memset(cst, 0x3f3f3f3f, sizeof cst);
    28         q.push(S), flw[S] = INF, cst[S] = 0;
    29         for (int tmp; q.size(); )
    30         {
    31             tmp = q.front(), q.pop(), inq[tmp] = 0;
    32             for (int i=head[tmp]; i!=-1; i=nxt[i])
    33             {
    34                 int v = edges[i].v;
    35                 if (cst[tmp]+edges[i].cst < cst[v]&&edges[i].f < edges[i].c){
    36                     cst[v] = cst[tmp]+edges[i].cst, bck[v] = i;
    37                     flw[v] = std::min(flw[tmp], edges[i].c-edges[i].f);
    38                     if (!inq[v]) q.push(v), inq[v] = 1;
    39                 }
    40             }
    41         }
    42         if (!flw[T]) break;
    43         for (int i=T; i!=S; i=edges[bck[i]].u)
    44             edges[bck[i]].f += flw[T], edges[bck[i]^1].f -= flw[T];
    45         ans += flw[T]*cst[T];
    46     }
    47 }
    48 int main()
    49 {
    50     memset(head, -1, sizeof head);
    51     scanf("%d%d",&n,&m);
    52     S = n+n+1, T = S+1, SS = T+1, TT = SS+1;
    53     for (int i=1,v; i<=n; i++)
    54     {
    55         scanf("%d",&v);
    56         addedge(S, i+n, v, 0);
    57         addedge(i, T, v, 0);
    58         addedge(SS, i, INF, 0);
    59         addedge(i+n, TT, INF, 0);
    60     }
    61     addedge(TT, SS, m, 0);
    62     for (int i=1; i<=n; i++)
    63         for (int j=1,x; j<=n-i; j++)
    64         {
    65             scanf("%d",&x);
    66             if (x!=-1) addedge(i+n, i+j, INF, x);
    67         }
    68     maxFlow();
    69     printf("%d
    ",ans);
    70     return 0;
    71 }

    END

  • 相关阅读:
    「日常训练」Single-use Stones (CFR476D2D)
    「日常训练」Greedy Arkady (CFR476D2C)
    「Haskell 学习」二 类型和函数(上)
    「学习记录」《数值分析》第二章计算实习题(Python语言)
    「日常训练」Alena And The Heater (CFR466D2D)
    Dubbo 消费者
    Dubbo 暴露服务
    Rpc
    git fail to push some refs....
    Spring Cloud (6)config 客户端配置 与GitHub通信
  • 原文地址:https://www.cnblogs.com/antiquality/p/10458859.html
Copyright © 2011-2022 走看看