网络流二十四题之十一 —— 航空路线问题(AIRL)
来源:互联网 发布:网络新媒体专业课程 编辑:程序博客网 时间:2024/05/21 21:33
航空路线问题
Description
给定一张航空图,图中顶点代表城市,边代表
现要求找出一条满足下述限制条件的且途经城市最多的旅行路线。
向西飞回起点(可途经若干城市)。
对于给定的航空图,试设计一个算法找出一条满足要求的最佳航空旅行路线。
Input
第
接下来的
城市名出现的顺序是从西向东。
也就是说,设
城市名是一个长度不超过
例如,
再接下来的
Output
第
接下来的
首先是出发城市名,然后按访问顺序列出其它城市名。
注意,最后
如果问题无解,则输出“No Solution!”。
Sample Input
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
Sample Output
7
Vancouver
Edmonton
Montreal
Halifax
Toronto
Winnipeg
Calgary
Vancouver
Solution
这是一道简单的费用流的题目。
一开始做这道题,我竟然没有发现必须要从西到东!
弄得我最开始求费用流时费了很大功夫。
步入正题。
首先,一去 —— 一回,我们完全可以看成最东方的那座城市有两条路径到最西方的城市!
将每个城市拆点,保证每个城市只经过一次。
然后将最西方的城市连上汇点,将最东方的城市连上源点。
将每一条航线的容量设为
然后求最大费用最大流即可。
注意:如果最西方的城市与最东方的城市直接连上了,那么这条边的容量应该为
Code
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <assert.h>
- #include <queue>
- #define MAXV 1000010
- #define MAXE 100010
- #define INF 0x3f3f3f3f
- #define Min(x,y) ((x)<(y)?(x):(y))
- #define ss 0
- #define tt 100005
- using namespace std;
- int n,m,ans,weight,tot;
- char s[110][50];
- char s1[50],s2[50];
- int from[MAXV],cnt,nxt[MAXV],wei[MAXV];
- int head[MAXE],dis[MAXE],data[MAXV],flow[MAXV];
- int pre[MAXE];
- bool in_stack[MAXE];
- queue<int>q;
- int come[4][500],come2[4][500];
- inline int in(){
- int x=0;
- char c=getchar();
- while(c<‘0’||c>‘9’)c=getchar();
- while(c>=‘0’&&c<=‘9’){x=x*10+c-‘0’;c=getchar();}
- return x;
- }
- void add(int x,int y,int a,int b){
- from[cnt]=x;nxt[cnt]=head[x];data[cnt]=y;wei[cnt]=b;flow[cnt]=a;head[x]=cnt++;
- from[cnt]=y;nxt[cnt]=head[y];data[cnt]=x;wei[cnt]=-b;flow[cnt]=0;head[y]=cnt++;
- }
- bool BFS(){
- memset(dis,0xc0,sizeof dis);
- q.push(ss);dis[ss]=0;in_stack[ss]=true;
- pre[ss]=pre[tt]=-1;
- while(!q.empty()){
- int now=q.front();
- q.pop();
- in_stack[now]=false;
- for(int i=head[now];i!=-1;i=nxt[i]){
- if(flow[i]&&wei[i]+dis[now]>dis[data[i]]){
- dis[data[i]]=wei[i]+dis[now];
- pre[data[i]]=(i^1);
- // if(data[i]==tt)break;
- if(!in_stack[data[i]]){q.push(data[i]);in_stack[data[i]]=true;}
- }
- }
- }
- return pre[tt]>0;
- }
- void dfs(){
- tot++;
- int Low=INF,tmp;
- for(int i=pre[tt];i!=-1;i=pre[data[i]])Low=Min(Low,flow[i^1]);
- for(int i=pre[tt];i!=-1;i=pre[data[i]]){
- flow[i^1]-=Low;
- flow[i]+=Low;
- come[tot][++come[tot][0]]=data[i];
- }
- tmp=come[tot][0]+1;
- for(int i=pre[tt];i!=-1;i=pre[data[i]])come2[tot][–tmp]=data[i]-n;
- weight+=Low;
- ans+=(dis[tt])*Low;
- }
- int main(){
- memset(head,-1,sizeof head);
- n=in();m=in();
- for(int i=1;i<=n;i++){
- scanf(”%s”,s[i]);
- if(i==1||i==n)add(i+n,i,2,0);
- else add(i+n,i,1,0);
- }
- add(ss,n+n,2,0);
- add(1,tt,2,0);
- for(int i=1;i<=m;i++){
- scanf(”%s%s”,s1,s2);
- int pos1,pos2;
- for(pos1=1;pos1<=n;pos1++)if(0==strcmp(s[pos1],s1))break;
- for(pos2=1;pos2<=n;pos2++)if(0==strcmp(s[pos2],s2))break;
- if(pos1==1&&pos2==n)add(pos2,pos1+n,2,1);
- else if(pos1==n&&pos2==1)add(pos1,pos2+n,2,1);
- else{
- if(pos1>pos2)add(pos1,pos2+n,1,1);
- else add(pos2,pos1+n,1,1);
- }
- }
- while(BFS())dfs();
- if(weight<2){
- printf(”No Solution!\n”);
- return 0;
- }
- else printf(“%d\n”,ans);
- for(int i=1;i<=come[1][0];i++)if(come[1][i]!=ss&&come[1][i]!=tt&&come[1][i]>=1&&come[1][i]<=n)printf(“%s\n”,s[come[1][i]]);
- // printf(“%d\n”,come[2][0]);
- for(int i=3;i<=come[2][0];i++)if(come2[2][i]!=ss&&come2[2][i]!=tt&&come2[2][i]>=1&&come2[2][i]<=n)printf(“%s\n”,s[come2[2][i]]);
- if(tot==1)for(int i=3;i<=come[1][0];i++)if(come2[1][i]!=ss&&come2[1][i]!=tt&&come2[1][i]>=1&&come2[1][i]<=n)printf(“%s\n”,s[come2[1][i]]);
- return 0;
- }
- 网络流二十四题之十一 —— 航空路线问题(AIRL)
- 航空路线问题[网络流24题之11]
- 网络流24题之T11 航空路线问题
- 【网络流24题】航空路线问题
- [网络流24题]航空路线问题
- 线性规划与网络流24——航空路线问题
- 网络流二十四题之二十四 —— 骑士共存问题(KNI)
- 网络流二十四题之十四 —— 孤岛营救问题(RESCUE)
- 线性规划与网络流24题 11航空路线问题
- 网络流与线性规划24题11航空路线问题
- [网络流24题 #11]航空路线问题
- 网络流24题11. 航空路线问题
- 「网络流 24 题」航空路线问题
- 航空路线问题 一般网络流
- 网络流二十四题之二 —— 太空飞行计划问题(SHUT)
- 【网络流24题】航空路线问题(最大费用流)
- loj6122「网络流 24 题」航空路线问题(最长不相交路径)
- 网络流二十四题之三 —— 最小路径覆盖问题(PATH)
- 199. Binary Tree Right Side View
- Java图形界面开发—列出指定目录
- 设计模式之原型模式
- C#当前日期时间
- hrbust/哈理工oj 1867 小伙伴的数据结构【树状数组】
- 网络流二十四题之十一 —— 航空路线问题(AIRL)
- 数组—— 2 sum, 3 sum, 3 sum closed, 4Sum.
- 华为在线训练之字符串分隔
- qsys初探————中断注册API
- 【LeetCode-105】Construct Binary Tree from Preorder and Inorder Traversal
- 慕课网二次学习(二)
- 可视化篇:Echarts个人轨迹可视化实现
- 博客新地址
- java类单继承,接口多继承设计的原因