• 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 }

    完~~~~~~~

    转载请注明出处.
  • 相关阅读:
    【学习】CodeUi
    【C#】权限修饰符
    链表_初步认识
    关于mysql8.0及以上版本连接navicat时候报错(密码加密方式需要修改)
    docker 运行mysql最新版本用navicat连接报错:1251
    spring5的基本组成(6个模块)
    关于java中设计原则总结(7)
    java中String中的endsWith()方法
    mysql中基本的语句
    mysql中索引类型
  • 原文地址:https://www.cnblogs.com/Miroerwf/p/7767161.html
Copyright © 2020-2023  润新知