Description
欧洲某城是一个著名的旅游胜地,每年都有成千上万的人前来观光旅行。Dr. Kong决定利用暑假好好游览一番。。
年轻人旅游不怕辛苦,不怕劳累,只要费用低就行。但Dr. Kong年过半百,他希望乘坐BUS从住的宾馆到想去游览的景点,期间尽可量地少换乘车。
Dr. Kon买了一张旅游地图。他发现,市政部门为了方便游客,在各个旅游景点及宾馆,饭店等地方都设置了一些公交站并开通了一些单程线路。每条单程线路从某个公交站出发,依次途经若干个站,最终到达终点站。
但遗憾的是,从他住的宾馆所在站出发,有的景点可以直达,有的景点不能直达,则他可能要先乘某路BUS坐上几站,再下来换乘同一站的另一路BUS, 这样须经过几次换乘后才能到达要去的景点。
为了方便,假设对该城的所有公交站用1,2,……,N编号。Dr. Kong所在位置的编号为1,他将要去的景点编号为N。
请你帮助Dr. Kong寻找一个最优乘车方案,从住处到景点,中间换车的次数最少。
Input
第一行: K 表示有多少组测试数据。(2≤k≤8)
接下来对每组测试数据:
第1行: M N 表示有M条单程公交线路,共有N站。(1<=M<=100 1<N<=500)
第2~M+1行: 每行描述一路公交线路信息,从左至右按运行顺序依次给出了该线路上的所有站号,相邻两个站号之间用一个空格隔开。
Output
对于每组测试数据,输出一行,如果无法乘坐任何线路从住处到达景点,则输出"N0",否则输出最少换车次数,输出0表示不需换车可以直达。
Sample Input
2 3 7 6 7 4 7 3 6 2 1 3 5 2 6 1 3 5 2 6 4 3
Sample Output
2 NO
Source
题解: 处理好每站的联系,把他们储存到图中是解题的关键. 之后就是简单的Dijkstra算法 求最短路...
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <limits.h> 5 #include <algorithm> 6 #include <iostream> 7 #include <ctype.h> 8 #include <iomanip> 9 #include <queue> 10 #include <stdlib.h> 11 using namespace std; 12 13 #define INF 0xffffff 14 #define N 550 15 int m,n; 16 int map[N][N]; 17 18 void Dijkstra() 19 { 20 int i,j,u,sum=0; 21 int book[N],dis[N],min; 22 memset(book,0,sizeof(book));//book数组初始化 23 //初始化dis数组,这里是1号顶点到其余各个顶点的初始路程 24 for(i=1;i<=n;i++) 25 dis[i]=map[1][i]; 26 book[1]=1; 27 28 //Dijkstra算法核心语句 29 for(i=1;i<=n-1;i++) 30 { 31 //找到离1号顶点最近的顶点 32 min=INF; 33 for(j=1;j<=n;j++) 34 { 35 if(book[j]==0 && dis[j]<min) 36 { 37 min=dis[j]; 38 u=j; 39 } 40 } 41 book[u]=1; 42 for(j=1;j<=n;j++) 43 { 44 if(map[u][j]<INF) 45 { 46 if(dis[j]>dis[u]+map[u][j]) 47 dis[j]=dis[u]+map[u][j]; 48 } 49 } 50 } 51 if(dis[n]>=INF) 52 printf("NO "); 53 else 54 printf("%d ",dis[n]-1); 55 } 56 57 int main() 58 { 59 int t; 60 scanf("%d",&t); 61 while(t--){ 62 int i,j,k=0,v; 63 char s[2000]; 64 int du[N]; 65 scanf("%d%d",&m,&n); 66 for(i=0;i<=N;i++){ 67 for(j=0;j<=N;j++){ 68 if(i==j) 69 map[i][j]=0; 70 else 71 map[i][j]=INF; 72 } 73 } 74 getchar(); 75 for(i=0;i<m;i++)//建图 76 { 77 k=0; 78 gets(s); 79 for(j=0;j<strlen(s);j++) 80 { 81 if(s[j]!=' ') 82 { 83 int sum=0; 84 while(s[j]!=' '&&j<strlen(s)) 85 { 86 sum=sum*10+(s[j]-'0');j++;//有可能是两位或更多位的数 87 } 88 du[k++]=sum; 89 } 90 } 91 for(j=0;j<k;j++) 92 { 93 for(v=j+1;v<k;v++) 94 { 95 map[du[j]][du[v]]=1; 96 } 97 } 98 } 99 Dijkstra(); 100 } 101 }