zoukankan      html  css  js  c++  java
  • 网络流24题航空路线问题

    跑最大费用最大流,把每个点拆开边权为1花费为1,连边时边权为1花费为0

    开头和结尾单独处理边权为2.

    字符串用map记录然后两遍dfs出结果即可。

    By:大奕哥

      1  #include<bits/stdc++.h>
      2 using namespace std;
      3 string ss,mpp[105];
      4 map<string,int>mmp;
      5 int n,m,head[205],d[205],f[205],cnt=-1,s,t,cost,ans[2][205];
      6 bool v[205];
      7 struct node{
      8     int nex,w,to,c,f;
      9 }e[10005];
     10 void add(int x,int y,int w,int c)
     11 {
     12     e[++cnt].to=y;e[cnt].f=x;e[cnt].nex=head[x];head[x]=cnt;e[cnt].w=w;e[cnt].c=c;
     13     e[++cnt].to=x;e[cnt].f=y;e[cnt].nex=head[y];head[y]=cnt;e[cnt].w=0;e[cnt].c=-c;
     14 }
     15 queue<int>q;
     16 bool spfa()
     17 {
     18     memset(v,0,sizeof(v));
     19     memset(d,0,sizeof(d));
     20     v[s]=1;q.push(s);
     21     memset(f,-1,sizeof(f));
     22     while(!q.empty())
     23     {
     24         int x=q.front();
     25         q.pop();v[x]=0;
     26         for(int i=head[x];i!=-1;i=e[i].nex)
     27         {
     28             int y=e[i].to;
     29             if(d[y]<d[x]+e[i].c&&e[i].w)
     30             {
     31                 d[y]=d[x]+e[i].c;
     32                 f[y]=i;
     33                 if(!v[y])v[y]=1,q.push(y);
     34             }
     35         }
     36     }
     37     if(d[t]==0)return 0;int inf=1e9;
     38     for(int i=f[t];i!=-1;i=f[e[i].f])inf=min(inf,e[i].w);
     39     for(int i=f[t];i!=-1;i=f[e[i].f])cost+=inf*e[i].c,e[i].w-=inf,e[i^1].w+=inf; 
     40     return 1;
     41 }
     42 void solve()
     43 {
     44     while(spfa());return;
     45 }
     46 void dfs(int x,int k)
     47 {
     48     if(x==n)
     49     {
     50         ans[k][++ans[k][0]]=x;return;
     51     }
     52     if(x%n!=ans[k][ans[k][0]])
     53     ans[k][++ans[k][0]]=x%n;
     54     for(int i=head[x];i!=-1;i=e[i].nex)
     55     {
     56         
     57         if(e[i^1].w)
     58         {
     59             e[i^1].w=0;
     60             dfs(e[i].to,k);
     61             return;
     62         }
     63     }
     64 }
     65 int main()
     66 {
     67     scanf("%d%d",&n,&m);
     68     memset(head,-1,sizeof(head));
     69     for(int i=1;i<=n;++i)
     70     {
     71         cin>>ss;
     72         mmp[ss]=i;
     73         mpp[i]=ss;
     74     }
     75     for(int i=1;i<=m;++i)
     76     {
     77         cin>>ss;
     78         int x=mmp[ss];
     79         cin>>ss;
     80         int y=mmp[ss];
     81         if(x==1&&y==n)
     82         add(x+n,y,2,0);
     83         add(x+n,y,1,0);
     84     }
     85     for(int i=2;i<n;++i)
     86     {
     87         add(i,i+n,1,1);
     88     }
     89     add(1,1+n,2,1);
     90     add(n,n+n,2,1);
     91     s=1;t=n*2;
     92     solve();
     93     if(!cost){
     94         puts("No Solution!");return 0;
     95     }
     96     printf("%d
    ",cost-2);
     97     dfs(n+1,1);
     98     dfs(n+1,0);
     99     for(int i=1;i<=ans[1][0];++i)cout<<mpp[ans[1][i]]<<endl;
    100     for(int i=ans[0][0]-1;i;--i)cout<<mpp[ans[0][i]]<<endl;
    101     return 0;
    102 }
  • 相关阅读:
    如何将数组初始化为全0?
    什么是优先级队列(priority queue)?
    C语言中指针的指针是如何工作的?
    什么是队列(Queue)?
    理解*ptr++
    【Luogu】P4172水管局长(LCT)
    【Luogu】P4159迷路(矩阵优化)
    【Luogu】P3971Alice And Bob(贪心)
    【Luogu】P3211XOR和路径(高斯消元)
    【Luogu】P2445动物园(最大流)
  • 原文地址:https://www.cnblogs.com/nbwzyzngyl/p/8383475.html
Copyright © 2011-2022 走看看