USACO Training Section 5.4 Canada Tour 周游加拿大

题目描述:
你赢得了一场航空公司举办的比赛,奖品是一张加拿大环游机票。旅行在这家航空公司开放的最西边的城市开始,然后一直自西向东旅行,直到你到达最东边的城市,再由东向西返回,直到你回到开始的城市。除了旅行开始的城市之外,每个城市只能访问一次,因为开始的城市必定要被访问两次(在旅行的开始和结束)。
当然不允许使用其他公司的航线或者用其他的交通工具。
给出这个航空公司开放的城市的列表,和两两城市之间的直达航线列表。找出能够访问尽可能多的城市的路线,这条路线必须满足上述条件,也就是从列表中的第一个城市开始旅行,访问到列表中最后一个城市之后再返回第一个城市。



输入输出格式
输入格式:
第 1 行: 航空公司开放的城市数 N 和将要列出的直达航线的数量 V。N 是一个不大于 100 的正整数。V 是任意的正整数。
第 2..N+1 行: 每行包括一个航空公司开放的城市名称。城市名称按照自西向东排列。不会出现两个城市在同一条经线上的情况。每个城市的名称都 是一个字符串,最多15字节,由拉丁字母表上的字母组成;城市名称中没有空格。
第 N+2..N+2+V-1 行: 每行包括两个城市名称(由上面列表中的城市名称组成),用一个空格分开。这样就表示两个城市之间的直达双程航线。
输出格式:
Line 1: 按照最佳路线访问的不同城市的数量 M。如果无法找到路线,输出 1。



输入输出样例
输入样例#1:
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
输出样例#1:
7

题目大意:

给定一个无向图,让你从1走到n再走回来,除1之外每个点只能经过一次,求经过的最大点数。

解题思路:

1.首先,对输入进行处理,把输入的字符串转化成点,使用“map”:传送门

2.我们可以转化一下,从一走到n再回到1,可以等效为,两个人一起从1出发,一个人走到n,另一个人走到一个和n直接相连的点。

题解:

附在了代码后面(习惯了~~~)

代码(c++)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<map>
 7 using namespace std;
 8 int n,m,f[101][101],v[5001][5001];/*f[i][j]表示第一人走到i,第二人走到j时经过的城市数*/
 9 string s[101];
10 map<string,int>b;
11 int main()
12 {
13     cin>>n>>m;
14     for(int i=1;i<=n;i++){
15         cin>>s[i]; b[s[i]]=i;
16     }/*将第i个字符串映射为i*/
17     for(int i=1;i<=m;i++){
18         string l,r; cin>>l>>r;
19         v[b[l]][b[r]]=1; v[b[r]][b[l]]=1;
20     }/*两点之间有路就变为1*/
21     f[1][1]=1;/*初始化*/
22     for(int i=1;i<=n;i++)
23         for(int j=i+1;j<=n;j++)
24             for(int k=1;k<j;k++){/*这3重循环和Floyed好像啊~~~~~*/
25                 if(v[k][j]&&f[i][k])/*如果k和j之间有道路,并且第一人到i,第二人到k这种情况是存在的,才可以转移*/
26                     f[i][j]=max(f[i][k]+1,f[i][j]);/*很简单的方程*/
27                 f[j][i]=f[i][j];/*第一人走到i,第二人走到j和第一人走到j,第二人走到i是等效的.*/
28             }
29     int ans=1;/*至少经过一个城市,就是起始城市*/
30     for(int i=1;i<=n;i++)
31         if(v[i][n])/*这个必须要加的,我们更新的是f[i][n],看下面↓↓↓,f[i][n]指的是: 1). 从1走到n(中间经过某些城市); 2).再从n直接走到i; 3). 然后从i经过某些道路走回1.基于第二点我们要保证n和i之间要有道路*/
32             ans=max(ans,f[i][n]);
33     cout<<ans;
34     return 0;
35 }

完~~~~~~~

转载请注明出处.
原文地址:https://www.cnblogs.com/Miroerwf/p/7767161.html