nyoj - 最少换乘 - dijkstra

题目描述:

 欧洲某城是一个著名的旅游胜地,每年都有成千上万的人前来观光旅行。Dr. Kong决定利用暑假好好游览一番。。

年轻人旅游不怕辛苦,不怕劳累,只要费用低就行。但Dr. Kong年过半百,他希望乘坐BUS从住的宾馆到想去游览的景点,期间尽可量地少换乘车。

 

Dr. Kon买了一张旅游地图。他发现,市政部门为了方便游客,在各个旅游景点及宾馆,饭店等地方都设置了一些公交站并开通了一些单程线路。每条单程线路从某个公交站出发,依次途经若干个站,最终到达终点站。

但遗憾的是,从他住的宾馆所在站出发,有的景点可以直达,有的景点不能直达,则他可能要先乘某路BUS坐上几站,再下来换乘同一站的另一路BUS, 这样须经过几次换乘后才能到达要去的景点。

 

为了方便,假设对该城的所有公交站用12……N编号。Dr. Kong所在位置的编号为1,他将要去的景点编号为N

请你帮助Dr. Kong寻找一个最优乘车方案,从住处到景点,中间换车的次数最少。

输入描述:

第一行:     K              表示有多少组测试数据。(2≤k≤8)
接下来对每组测试数据:
第1行:       M  N        表示有M条单程公交线路,共有N站。(1<=M<=100 1<N<=500)
第2~M+1行: 每行描述一路公交线路信息,从左至右按运行顺序依次给出了该线路上的所有站号,相邻两个站号之间用一个空格隔开。

输出描述:

对于每组测试数据,输出一行,如果无法乘坐任何线路从住处到达景点,则输出"N0",否则输出最少换车次数,输出0表示不需换车可以直达。

样例输入:

复制
2
3 7
6 7
4 7 3 6
2 1 3 5
2 6
1 3 5
2 6 4 3

样例输出:

2
NO

提示:

没有提示哦

来源:

第八届河南省程序设计大赛
分析:

最短路径的变形……

注意两点:

(1)输入问题,一次读一行,注意有的城市可能是2、3位数,比如123

(2)建边问题,把一条线上的边值建为1,然后用dijkstra,得出的值减一就是最后结果

刚开始不理解为什么“把一条线上的边值建为1”,当时想要是起点,终点在一条线上不就错了吗,(智障想法)

比如:1起点,7终点

1 7 3  把1到7,1到3,7到3的边都建为1,1到7的最短换乘为1-1=0

(在一条线路上不管走几个点,值都是1,一跨线路,值加一)

代码如下:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=505,INF=0x3f3f3f3f;
int n,cost[N][N],d[N],vis[N],city[N];
void init(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(i==j)cost[i][j]=1;
            else cost[i][j]=INF;
        }
    }
}

void dijkstra(int s){
    memset(vis,0,sizeof(vis));
    memset(d,INF,sizeof(d));
    d[s]=0;
    for(int k=1;k<=n;k++){
        int v=-1;
        for(int i=1;i<=n;i++){
            if(!vis[i]&&(v==-1||d[i]<d[v]))v=i;
        }
        vis[v]=1;
        for(int i=1;i<=n;i++){
            d[i]=min(d[i],d[v]+cost[v][i]);
        }
    }
}

int main(){
    int m,t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&m,&n);
        getchar();
        init();
        while(m--){
            memset(city,0,sizeof(city));
            string s;
            getline(cin,s);
            int len=s.length();
            int x,k,q=0;
            for(int i=0;i<len;){
                if(s[i]!=' '){
                    x=s[i]-'0';
                    k=i+1;
                    while(s[k]!=' '&&k<len){
                        x=x*10+s[k]-'0';
                        k++;
                    }
                    i=k;
                    city[q++]=x;
                }
                else i++;
            }
            for(int i=0;i<q;i++){
                for(int j=i+1;j<q;j++){
                    cost[city[i]][city[j]]=1;
                }
            }
        }

        dijkstra(1);
        if(d[n]>=INF)printf("NO\n");
        else if(n==1)printf("0\n");
        else printf("%d\n",d[n]-1);
    }
}

猜你喜欢

转载自blog.csdn.net/m0_37579232/article/details/80274075