zoukankan      html  css  js  c++  java
  • 【uva1658 算法竞赛入门经典】海军上将【费用流】

    题意

      给出一个v(3<=v<=1000)个点e(3<=e<=10000)条边的有向加权图,求1-v的两条不相交(除了起点和终点外没有公共点)的路径,使得权和最小。

    分析

     费用流的一个经典用法就是限制没有公共边边,但是这个题有个不同,这个题限制的是没有公共点。因此,我们把每个点拆出一条边来。

    把2到v-1的每个结点i拆成i和i‘两个结点,中间连一条容量为1,费用为0的边。对于原图中的每一条边(a,b),连一条弧(a',b),容量为1,费用为权值然后求1到v的流量为2的最小费用流即可。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <queue>
     6 
     7 using namespace std;
     8 const int maxn=4000+10;
     9 const int maxm=40000+10;
    10 const int INF=2147480000;
    11 struct MCMF{
    12     int head[maxn],Next[maxm],to[maxm],from[maxm],flow[maxm],cap[maxm],cost[maxm];
    13     int inq[maxn],d[maxn],p[maxn],a[maxn];
    14     int n,m,s,t,sz;
    15     void init(int n){
    16         this->n=n;
    17         sz=-1;
    18         memset(head,-1,sizeof(head));
    19     }
    20     void add_edge(int a,int b,int ca,int co){
    21         ++sz;
    22         from[sz]=a;to[sz]=b;Next[sz]=head[a];head[a]=sz;
    23         cap[sz]=ca;cost[sz]=co;flow[sz]=0;
    24         ++sz;
    25         from[sz]=b;to[sz]=a;Next[sz]=head[b];head[b]=sz;
    26         cap[sz]=ca;cost[sz]=-co;flow[sz]=ca;
    27     }
    28     bool spfa(int s,int t,int &Flow ,long long &Cost){
    29         for(int i=0;i<=n;i++)d[i]=INF;
    30         queue<int>Q;
    31         memset(inq,0,sizeof(inq));
    32         d[s]=0;inq[s]=1;p[s]=-1;a[s]=INF;
    33         Q.push(s);
    34         while(!Q.empty()){
    35             int u=Q.front();Q.pop();
    36             inq[u]=0;
    37             for(int i=head[u];i!=-1;i=Next[i]){
    38                 int v=to[i];
    39                 if(cap[i]>flow[i]&&d[v]>d[u]+cost[i]){
    40                     d[v]=d[u]+cost[i];
    41                     p[v]=i;
    42                     a[v]=min(a[u],cap[i]-flow[i]);
    43                     if(!inq[v]){
    44                         inq[v]=1;
    45                         Q.push(v);
    46                     }
    47                 }
    48             }
    49         }
    50         if(d[t]==INF)return false;
    51         Flow+=a[t];
    52         Cost+=(long long)a[t]*(long long)d[t];
    53         int u=t;
    54         while(u!=s){
    55             flow[p[u]]+=a[t];
    56             flow[p[u]^1]-=a[t];
    57             u=from[p[u]];
    58         }
    59         return true;
    60     }
    61     long long Mincost(int s,int t){
    62         int Flow=0;
    63         long long Cost=0;
    64         while(spfa(s,t,Flow,Cost));
    65         return Cost;
    66     }
    67 }mcmf;
    68 int n,m;
    69 int main(){
    70     while(scanf("%d%d",&n,&m)!=EOF){
    71         int a,b,c;
    72         mcmf.init(2*n);
    73         for(int i=2;i<n;i++){
    74             mcmf.add_edge(i,i+n,1,0);
    75         }
    76         mcmf.add_edge(1,n+1,2,0);
    77         mcmf.add_edge(n,2*n,2,0);
    78         for(int i=1;i<=m;i++){
    79             scanf("%d%d%d",&a,&b,&c);
    80             mcmf.add_edge(a+n,b,1,c);
    81         }
    82         int ans=mcmf.Mincost(1,2*n);
    83         cout<<ans<<endl;
    84     }
    85 return 0;
    86 }
    View Code

     

  • 相关阅读:
    iOS应用程序的登录界面
    访问Mac下virtualbox中的win8.1虚拟机
    JASIG-CAS学习笔记——初探CAS
    跨域读取Cookies(续)
    跨域读取Cookies
    错误——无法找到com/* /* /**.xml
    设计模式学习之——简单工厂、工厂方法、抽象工厂方法
    spring+ibatis+dwr+ext项目整合
    SenchaTouch学习——form表单
    FLEX自定义事件
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9305189.html
Copyright © 2011-2022 走看看