• 【网络流24题】No.11(航空路线问题 最长不相交路径 最大费用流)


    【题意】

      给定一张航空图, 图中顶点代表城市, 边代表 2 城市间的直通航线。 现要求找出一条满足下述限制条件的且途经城市最多的旅行路线。
    (1) 从最西端城市出发,单向从西向东途经若干城市到达最东端城市,然后再单向从东向西飞回起点(可途经若干城市) 。
    (2) 除起点城市外, 任何城市只能访问 1 次。

    输入文件示例
    input.txt
    8 9
    Vancouver
    Yellowknife
    Edmonton
    Calgary
    Winnipeg
    Toronto
    Montreal
    Halifax
    Vancouver Edmonton
    Vancouver Calgary
    Calgary Winnipeg
    Winnipeg Toronto
    Toronto Halifax
    Montreal Halifax
    Edmonton Montreal
    Edmonton Yellowknife
    Edmonton Calgary

    输出文件示例
    output.txt
    7
    Vancouver
    Edmonton
    Montreal
    Halifax
    Toronto
    Winnipeg
    Calgary
    Vancouver

    【分析】

      只有我这种智障才会想半天 保证 从西向东怎么破吧。。

      都知道是怎么做的了。。。

      这种回路其实相当于从起点到终点走两次  然后路径不相交。

      不相交这一点约束了我们不能把两次路径分开做的。。  

      点只能走一遍,拆点,流量为1,费用为1.

      然后按照原图也建边。(只能从西往东走,双向边事实上只建一条)

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<queue>
      7 #include<cmath>
      8 #include<map>
      9 using namespace std;
     10 #define Maxn 2010
     11 #define INF 0xfffffff
     12 
     13 map<string,int> M;
     14 int n,m;
     15 
     16 struct node
     17 {
     18     int x,y,f,o,c,next;
     19 }t[Maxn*1010];int len;
     20 int first[Maxn];
     21 
     22 int mymin(int x,int y) {return x<y?x:y;}
     23 int mymax(int x,int y) {return x>y?x:y;}
     24 
     25 void ins(int x,int y,int f,int c)
     26 {
     27     t[++len].x=x;t[len].y=y;t[len].f=f;t[len].c=c;
     28     t[len].next=first[x];first[x]=len;t[len].o=len+1;
     29     t[++len].x=y;t[len].y=x;t[len].f=0;t[len].c=-c;
     30     t[len].next=first[y];first[y]=len;t[len].o=len-1;
     31 }
     32 
     33 int st,ed;
     34 queue<int > q;
     35 int dis[Maxn],pre[Maxn],flow[Maxn];
     36 bool inq[Maxn];
     37 bool bfs()
     38 {
     39     while(!q.empty()) q.pop();
     40     memset(dis,-1,sizeof(dis));
     41     memset(inq,0,sizeof(inq));
     42     q.push(st);dis[st]=0;flow[st]=INF;inq[st]=1;
     43     while(!q.empty())
     44     {
     45         int x=q.front();
     46         for(int i=first[x];i;i=t[i].next) if(t[i].f>0)
     47         {
     48             int y=t[i].y;
     49             if(dis[y]<dis[x]+t[i].c)
     50             {
     51                 dis[y]=dis[x]+t[i].c;
     52                 pre[y]=i;
     53                 flow[y]=mymin(flow[x],t[i].f);
     54                 if(!inq[y])
     55                 {
     56                     inq[y]=1;
     57                     q.push(y);
     58                 }
     59             }
     60         }
     61         inq[x]=0;q.pop();
     62     }
     63     if(dis[ed]==-1) return 0;
     64     return 1;
     65 }
     66 
     67 void output()
     68 {
     69     for(int i=1;i<=len;i+=2)
     70      printf("%d->%d %d %d
    ",t[i].x,t[i].y,t[i].f,t[i].c);
     71     printf("
    ");
     72 }
     73 
     74 void max_flow()
     75 {
     76     int ans=0,sum=0;
     77     while(bfs())
     78     {
     79         sum+=dis[ed]*flow[ed];
     80         ans+=flow[ed];
     81         int now=ed;
     82         while(now!=st)
     83         {
     84             t[pre[now]].f-=flow[ed];
     85             t[t[pre[now]].o].f+=flow[ed];
     86             now=t[pre[now]].x;
     87         }
     88     }
     89     if(ans<2) printf("No Solution!
    ");
     90     else
     91     {
     92         printf("%d
    ",sum-2);
     93     }
     94 }
     95 
     96 string s[Maxn],ss;
     97 bool vis[Maxn*Maxn];
     98 void dfs(int x,bool qq)
     99 {
    100     if(x==n) return;
    101     if(x<n) 
    102     {
    103         if(qq) cout<<s[x]<<endl;
    104         dfs(x+n,qq);
    105         if(!qq) cout<<s[x]<<endl;
    106         return;
    107     }
    108     for(int i=first[x];i;i=t[i].next) if(t[i].f==0&&!vis[i])
    109     {
    110         vis[i]=1;
    111         dfs(t[i].y,qq);
    112         return;
    113     }
    114 }
    115 
    116 void init()
    117 {
    118     scanf("%d%d",&n,&m);
    119     for(int i=1;i<=n;i++)
    120     {
    121         cin>>s[i];
    122         M[s[i]]=i;
    123     }
    124     for(int i=1;i<=m;i++)
    125     {
    126         int x,y,tt;
    127         cin>>ss;
    128         x=M[ss];
    129         cin>>ss;
    130         y=M[ss];
    131         if(x==1&&y==n) ins(x+n,y,2,0);
    132         else ins(x+n,y,1,0);
    133     }
    134     st=1;ed=n+n;
    135     ins(1,1+n,2,1);ins(n,n+n,2,1);
    136     for(int i=2;i<n;i++) ins(i,i+n,1,1);
    137     memset(vis,0,sizeof(vis));
    138 }
    139 
    140 int main()
    141 {
    142     init();
    143     max_flow();
    144     dfs(1,1);
    145     cout<<s[n]<<endl;
    146     dfs(1,0);
    147     return 0;
    148 }
    View Code

    有没有SBJ ,桑心。。。

    本机测的最长路径长度是对的,方案懒得看了,应该没什么问题吧。。

    2016-11-04 19:39:24

  • 相关阅读:
    约瑟夫解决问题的循环链表
    [Erlang危机](5.1.0)VM检测概述
    找呀志_java网络编程(5)TCP和udp差额
    有序输出两棵二叉查找树中的元素
    1234567选择3个数字组合
    八皇后问题
    矩阵乘法运算
    求π的近似值
    证明不小于6的偶数都是两个素数之和
    最大公约数最小公倍数
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6031493.html
Copyright © 2020-2023  润新知