【codevs1722】【NOI1997】最优乘车,单元最短路?

1722 最优乘车 1997年NOI全国竞赛
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 大师 Master
题解
题目描述 Description
H城是一个旅游胜地,每年都有成千上万的人前来观光。为方便游客,巴士公司在各个旅游景点及宾馆,饭店等地都设置了巴士站并开通了一些单程巴上线路。每条单程巴士线路从某个巴士站出发,依次途经若干个巴士站,最终到达终点巴士站。

一名旅客最近到H城旅游,他很想去S公园游玩,但如果从他所在的饭店没有一路巴士可以直接到达S公园,则他可能要先乘某一路巴士坐几站,再下来换乘同一站台的另一路巴士, 这样换乘几次后到达S公园。

现在用整数1,2,…N 给H城的所有的巴士站编号,约定这名旅客所在饭店的巴士站编号为1…S公园巴士站的编号为N。

写一个程序,帮助这名旅客寻找一个最优乘车方案,使他在从饭店乘车到S公园的过程中换车的次数最少。

输入描述 Input Description
输入文件是INPUT.TXT。文件的第一行有两个数字M和N(1<=M<=100 N<=500),表示开通了M条单程巴士线路,总共有N个车站。从第二行到第M刊行依次给出了第1条到第M条巴士线路的信息。其中第i+1行给出的是第i条巴士线路的信息,从左至右按运行顺序依次给出了该线路上的所有站号相邻两个站号之间用一个空格隔开。

输出描述 Output Description
输出文件是OUTPUT.TXT,文件只有一行。如果无法乘巴士从饭店到达S公园,则输出”N0”,否则输出你的程序所找到的最少换车次数,换车次数为0表示不需换车即可到达。

样例输入 Sample Input
3 7

6 7

4 7 3 6

2 1 3 5

样例输出 Sample Output
2
写在前面:比较蛋疼的一个题目(:з」∠)
——————————————————————————————————————————————
解题思路:读入就是个大麻烦,我是读入每一行然后分别截取,用c_str读到a数组里,然后再转换到邻接矩阵g里,然后floyed就可以了
代码:

#include<cstdio>
#include<string> 
#include<iostream>
#include<cstring>
using namespace std;
int n,m,a[101][501],g[501][501];
string s,s1;
main()
{
    scanf("%d%d\n",&m,&n);
    for (int i=1;i<=m;i++)
    {   
        getline(cin,s);
        int head=0,tail=0;
        for (int j=0;j<=s.length()-1;j++)
        {
            if (s[j]!=' ') tail++;//tail记录数字长度
            else
            {
                s1=s.substr(head,tail);
                a[i][0]++;
                sscanf(s1.c_str(),"%d",&a[i][a[i][0]]);//a[i][0]记录第i条路径上的车站数            
                    head=tail+head+1;//head记录下一个数字的起始位置
                tail=0;
            }
        }
        s1=s.substr(head,tail);
        a[i][0]++;
        sscanf(s1.c_str(),"%d",&a[i][a[i][0]]);//再读入一次因为最后是回车,读不进去
    }
    memset(g,15,sizeof(g));//把g数组初始化成无限大
    for (int i=1;i<=n;i++) g[i][i]=0;//自己到自己的距离为0
    for (int i=1;i<=m;i++)
    for (int j=1;j<=a[i][0];j++)
    for (int k=j+1;k<=a[i][0];k++) g[a[i][j]][a[i][k]]=1;//单元路径,将几个点连接
        for (int k=1;k<=n;k++)
    for (int i=1;i<=n;i++)
    for (int j=1;j<=n;j++)
    g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
    if (g[1][n]<1000000)
    printf("%d",g[1][n]-1);
    else printf("NO"); 
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值