码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2016-11-04 21:08:02      阅读:321      评论:0      收藏:0      [点我收藏+]

标签:起点   cout   app   queue   input   std   ++   code   else   

【题意】

  给定一张航空图, 图中顶点代表城市, 边代表 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\n",t[i].x,t[i].y,t[i].f,t[i].c);
 71     printf("\n");
 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!\n");
 90     else
 91     {
 92         printf("%d\n",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

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

标签:起点   cout   app   queue   input   std   ++   code   else   

原文地址:http://www.cnblogs.com/Konjakmoyu/p/6031493.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!