NKOI 1946 航空路线
来源:互联网 发布:淘宝直通车一天烧50万 编辑:程序博客网 时间:2024/05/01 09:14
【线性规划与网络流24题 11】航空路线
Time Limit:10000MS Memory Limit:65536K
Total Submit:18 Accepted:2
Case Time Limit:1000MS
Description
给定一张航空图,图中顶点代表城市,边代表2城市间的直通航线。现要求找出一条满足下述限制条件的且途经城市最多的旅行路线。
(1)从最西端城市出发,单向从西向东途经若干城市到达最东端城市,然后再单向从东向西飞回起点(可途经若干城市)。
(2)除起点城市外,任何城市只能访问1次。
编程任务:
对于给定的航空图,试设计一个算法找出一条满足要求的最佳航空旅行路线。
由于本OJ无Special Judge , 所以只需要输出最多经过的城市数
Input
第1 行有2个正整数N 和V,N 表示城市数,N<100,V 表示直飞航线数。
接下来的N行中每一行是一个城市名,可乘飞机访问这些城市。
城市名出现的顺序是从西向东。也就是说,设i,j 是城市表列中城市出现的顺序,当i>j 时,表示城市i 在城市j 的东边,而且不会有2 个城市在同一条经线上。城市名是一个长度不超过15 的字符串,串中的字符可以是字母或阿拉伯数字。例如,AGR34或BEL4。
再接下来的V 行中,每行有2 个城市名,中间用空格隔开,如 city1 city2 表示city1到city2 有一条直通航线,从city2 到city1 也有一条直通航线。
Output
一行,包含一个整数或字符串,表示最多经过的城市数,如果无解,则输出"No Solution!"(不包含引号)
Sample Input
8 9VancouverYellowknifeEdmontonCalgaryWinnipegTorontoMontrealHalifaxVancouver EdmontonVancouver CalgaryCalgary WinnipegWinnipeg TorontoToronto HalifaxMontreal HalifaxEdmonton MontrealEdmonton YellowknifeEdmonton Calgary
Sample Output
7
Source
感谢 Wo_ai_WangYuan 修改题目并放上数据
这题要用到最大费用最大流
把问题抽象成图论问题,数学模型是求从S到T的两条不相交的路径,使得路径上点的权值之和最大。
费用流建模,首先拆点,把顶点x拆成x和x',x 与x'之间连接一条费用为1,容量为1的有向边;
特殊地,1和n两个节点拆分后点内边容量设为2
对于与x相连的点a(a>x)x'向a连一条费用为0,容量为1的边。
最后再特判一下无解的情况
#include<cstdio>#include<iostream>#include<cstring>#include<map> #include<vector>#include<queue>using namespace std;const int maxn=505,inf=1e9;string ss,tt;int n,m,last[maxn],path[maxn],op,ed;int dis[maxn],vd[maxn],maxflow,mincost;bool flag[maxn];map<string,int>id;struct wr{ int a,b,c,w,NEXT; wr(int a,int b,int w,int c,int NEXT):a(a),b(b),w(w),c(c),NEXT(NEXT){} }; vector<wr>s; void insert(int a,int b,int w,int c){ s.push_back(wr(a,b,w,c,last[a])); last[a]=s.size()-1; s.push_back(wr(b,a,-w,0,last[b])); last[b]=s.size()-1; } struct wk{ int n; void init(int n){ this->n =n; memset(last,-1,sizeof(last)); } bool find(int st,int nd){ int i; queue<int>q; for(i=1;i<=n;i++)dis[i]=-inf,path[i]=-1; dis[st]=0,path[st]=0,flag[st]=1; q.push(st); while(!q.empty()){ int x=q.front(); q.pop();flag[x]=0; for(i=last[x];i!=-1;i=s[i].NEXT){ wr& e=s[i]; if(e.c>0&&dis[x]+e.w>dis[e.b]){ dis[e.b]=dis[x]+e.w; path[e.b]=i; if(!flag[e.b]){ q.push(e.b) ; flag[e.b]=1; } } } } return dis[nd]>-inf; } }spfa; void addflow(){ int flow=inf,i; for(i=ed;i!=op&&s[path[i]].a!=0;i=s[path[i]].a) flow=min(flow,s[path[i]].c); maxflow+=flow; mincost+=dis[ed]*flow; for(i=ed;i!=op;i=s[path[i]].a){ int x=path[i]; s[x].c-=flow; s[x^1].c+=flow; } } int main(){cin>>n>>m;int i,j;op=1,ed=2*n;spfa.init(ed);for(i=1;i<=n;i++){cin>>ss;id[ss]=i;if(i==1||i==n)insert(i,i+n,1,2);else insert(i,i+n,1,1);}for(i=1;i<=m;i++){cin>>ss>>tt;int id1=id[ss],id2=id[tt];if(id1>id2)swap(id1,id2);insert(id1+n,id2,0,1);}while(spfa.find(op,ed))addflow(); if(maxflow==1&&mincost==2) printf("2"); else if(maxflow!=2)printf("No Solution!"); else printf("%d",mincost-2);}
- NKOI 1946 航空路线
- 航空路线问题
- P2770 航空路线问题
- 洛谷 P2770 航空路线问题
- 航空路线问题 一般网络流
- 【网络流24题】航空路线问题
- [网络流24题]航空路线问题
- 线性规划与网络流24题 11航空路线问题
- 网络流与线性规划24题11航空路线问题
- [网络流24题 #11]航空路线问题
- 航空路线问题[网络流24题之11]
- 【线性规划与网络流24题 11】航空路线
- 线性规划与网络流24——航空路线问题
- 网络流24题11. 航空路线问题
- 网络流24题之T11 航空路线问题
- 「网络流 24 题」航空路线问题
- 网络流二十四题之十一 —— 航空路线问题(AIRL)
- 【网络流24题】航空路线问题(最大费用流)
- 关于Android中一些异常问题的解决办法
- QT Udp组播
- 各聚类算法比较
- 解剖学概述
- spring mvc 表单提交
- NKOI 1946 航空路线
- 【47】3求1+2+3+...+n
- poj 2653 Pick-up sticks 线段相交
- 数据结构实验之二叉树五:层序遍历
- Poj 2195 Going Home【费用流Min_Cost_Max_flow】
- Nmap的用法与基本命令
- jquery中的过滤filter not的用法以及可以添加this
- 【Struts】--EL表达式罢工了
- windows C++进程间和线程间通信