zoukankan      html  css  js  c++  java
  • HDU 1853 Cyclic Tour

    题意:Little Tom要“环”游一些城市,每个城市只能游玩一次。现在给出一张有向图和每条边的费用。求最小费用。

    要走环,很容易想到二分图匹配。这里还是一样的,拆点。把每个点拆开,变成i,i',分别和源点S汇点T相连,费用是0,容量是1。然后对原图中的每条边(u,v),对应边(u,v',1,cost),跑费用流,如果最大流=城市数,说明存在一个方案,答案就是最小费用流算出来的费用。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <queue>
     5 #define maxn 210
     6 #define maxm 100000
     7 #define INF 1<<30
     8 using namespace std;
     9 struct MCMF{
    10     int src,sink,e,n;
    11     int first[maxn];
    12     int cap[maxm],cost[maxm],v[maxm],next[maxm];
    13     void init(){
    14         e = 0;
    15         memset(first,-1,sizeof(first));
    16     }
    17     void add_edge(int a,int b,int cc,int ww){
    18         v[e] = b;next[e] = first[a];cap[e] = cc;
    19         cost[e] = ww;first[a] = e++;
    20         v[e] = a;next[e] = first[b];cap[e] = 0;
    21         cost[e] = -ww;first[b] = e++;
    22     }
    23 
    24     int d[maxn],pre[maxn],pos[maxn];
    25     bool vis[maxn];
    26 
    27     bool spfa(int s,int t){
    28         memset(pre,-1,sizeof(pre));
    29         memset(vis,0,sizeof(vis));
    30         queue<int> Q;
    31         for(int i = 0;i <= n;i++)   d[i] = INF;
    32         Q.push(s);pre[s] = s;d[s] = 0;vis[s] = 1;
    33         while(!Q.empty()){
    34             int u = Q.front();Q.pop();
    35             vis[u] = 0;
    36             for(int i = first[u];i != -1;i = next[i]){
    37                 if(cap[i] > 0 && d[u] + cost[i] < d[v[i]]){
    38                     d[v[i]] = d[u] + cost[i];
    39                     pre[v[i]] = u;pos[v[i]] = i;
    40                     if(!vis[v[i]])  vis[v[i]] = 1,Q.push(v[i]);
    41                 }
    42             }
    43         }
    44         return pre[t] != -1;
    45     }
    46 
    47     int Mincost,Maxflow;
    48     int MincostFlow(int s,int t,int nn){
    49         Mincost = Maxflow = 0,n = nn;
    50         while(spfa(s,t)){
    51             int min_f = INF;
    52             for(int i = t;i != s;i = pre[i])
    53                 if(cap[pos[i]] < min_f) min_f = cap[pos[i]];
    54             Mincost += d[t] * min_f;
    55             Maxflow += min_f;
    56             for(int i = t;i != s;i = pre[i]){
    57                 cap[pos[i]] -= min_f;
    58                 cap[pos[i]^1] += min_f;
    59             }
    60         }
    61         return Mincost;
    62     }
    63 };
    64 MCMF g;
    65 
    66 int main()
    67 {
    68     int n,m;
    69     while(scanf("%d%d",&n,&m) == 2){
    70         g.init();
    71         int S = 0,T = 2*n+1;
    72         for(int i = 1;i <= n;i++){
    73             g.add_edge(S,i,1,0);
    74             g.add_edge(i+n,T,1,0);
    75         }
    76         for(int i = 1;i <= m;i++){
    77             int a,b,c;
    78             scanf("%d%d%d",&a,&b,&c);
    79             g.add_edge(a,b+n,1,c);
    80         }
    81         int ans = g.MincostFlow(S,T,T);
    82         if(g.Maxflow == n)  printf("%d
    ",ans);
    83         else printf("-1
    ");
    84     }
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    Filebeat
    kafka 分区 spark excutor task rdd
    Java 方法重写方法重载
    Spark union
    Storm
    pbuilder编译构建工具分析
    TCP的拥塞控制 (四)
    TCP的拥塞控制 (三)
    TCP的拥塞控制 (二)
    TCP的拥塞控制 (一)
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3422817.html
Copyright © 2011-2022 走看看