描述
你赢得了一场航空公司举办的比赛,奖品是一张加拿大环游机票。旅行在这家航空公司开放的最西边的城市开始,然后一直自西向东旅行,直到你到达最东边的城市,再由东向西返回,直到你回到开始的城市。除了旅行开始的城市之外,每个城市只能访问一次,因为开始的城市必定要被访问两次(在旅行的开始和结束)。
当然不允许使用其他公司的航线或者用其他的交通工具。
给出这个航空公司开放的城市的列表,和两两城市之间的直达航线列表。找出能够访问尽可能多的城市的路线,这条路线必须满足上述条件,也就是从列表中的第一个城市开始旅行,访问到列表中最后一个城市之后再返回第一个城市。
PROGRAM NAME: tour
INPUT FORMAT
Line 1: 航空公司开放的城市数 N 和将要列出的直达航线的数量 V。N 是一个不大于 100 的正整数。V 是任意的正整数。
Lines 2..N+1: 每行包括一个航空公司开放的城市名称。城市名称按照自西向东排列。不会出现两个城市在同一条经线上的情况。每个城市的名称都 是一个字符串,最多15字节,由拉丁字母表上的字母组成;城市名称中没有空格。
Lines N+2..N+2+V-1: 每行包括两个城市名称(由上面列表中的城市名称组成),用一个空格分开。这样就表示两个城市之间的直达双程航线。
OUTPUT FORMAT
Line 1: 按照最佳路线访问的不同城市的数量 M。如果无法找到路线,输出 1。
Analysis
题目越来越难了
一开始是没想到要dp的,后面看了一发题解;P
由于i到j和j到i是等价的,那么题目可以看成是找两条从1出发其中一条到n的最长路径,那么
f[i][j]
表示第一个人到i第二个人到j的最长路转移
f[i][j]=f[i][k]+1
若k与j之间有一条边且
f[i][k]≥0
由于两人可以交换,那么
f[i][j]=f[j][i]
城市名怎么变成标号?STL大法好!!
Code
/*
ID:wjp13241
PROG:tour
LANG:C++
*/
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <map>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define dfo(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,x,e) for(int i=ls[x];i;i=e[i].next)
#define fil(x,t) memset(x,t,sizeof(x))
#define STP system("pause")
#define min(x,y) x<y?x:y
#define max(x,y) x>y?x:y
#define MP(x,y) make_pair(x,y)
#define PuB(v,x) v.push_back(x)
#define PoB(v) v.pop_back()
#define ld long double
#define ll long long
#define db double
#define INF 0x3f3f3f3f
#define LIM 100000000
#define EPS 1e-4
#define N 201
#define E N*20+1
using namespace std;
int f[N][N],p[N][N];
int main()
{
freopen("tour.in","r",stdin);
freopen("tour.out","w",stdout);
ios::sync_with_stdio(false);
int n,m;
cin>>n>>m;
map<string,int>word;
fo(i,1,n)
{
string x;
cin>>x;
word.insert(MP(x,i));
}
fo(i,1,m)
{
string x,y;
cin>>x>>y;
p[word[x]][word[y]]=p[word[y]][word[x]]=1;
}
f[1][1]=1;
fo(i,1,n)
fo(j,i+1,n)
{
fo(k,1,n)
if (f[i][k]>0&&p[k][j])
f[i][j]=max(f[i][j],f[i][k]+1);
f[j][i]=f[i][j];
}
int ans=1;
fo(i,1,n-1)
if (p[i][n])
ans=max(ans,f[i][n]);
cout<<ans<<endl;
return 0;
}