• 【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

     

  • 相关阅读:
    DRF的Filter:字段过滤,查找,排序
    DRF的ViewSet和Router
    DRF的APIView和mixins+GenericAPIView和ListAPIView
    DRF的Serializer和ModelSerializer
    html5中的drag
    excel与json转换
    call和bind的原生实现
    将字符串转化为条形码,在将canvas转化为图片
    JSON与excel之间的相互转化(Vue)
    js实现点击复制,将内容复制至剪贴板
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/9305189.html
Copyright © 2020-2023  润新知