最少换乘
时间限制:
2000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
欧洲某城是一个著名的旅游胜地,每年都有成千上万的人前来观光旅行。Dr. Kong决定利用暑假好好游览一番。。
年轻人旅游不怕辛苦,不怕劳累,只要费用低就行。但Dr. Kong年过半百,他希望乘坐BUS从住的宾馆到想去游览的景点,期间尽可量地少换乘车。
Dr. Kon买了一张旅游地图。他发现,市政部门为了方便游客,在各个旅游景点及宾馆,饭店等地方都设置了一些公交站并开通了一些单程线路。每条单程线路从某个公交站出发,依次途经若干个站,最终到达终点站。
但遗憾的是,从他住的宾馆所在站出发,有的景点可以直达,有的景点不能直达,则他可能要先乘某路BUS坐上几站,再下来换乘同一站的另一路BUS, 这样须经过几次换乘后才能到达要去的景点。
为了方便,假设对该城的所有公交站用1,2,……,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
-
第一行: K 表示有多少组测试数据。(2≤k≤8)
AC代码:
# include <stdio.h>
# include <string.h>
# define M 505
# define STRM 20005
# define INF 10000000
int map[M][M];
char str[STRM];
int n, m;
int num[M];
void printMap()
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
printf("%-3d ", map[i][j]);
}
printf("\n");
}
}
void InitMap() //初始化地图
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i == j)
{
map[i][j] = 0;
}
else
{
map[i][j] = INF;
}
}
}
}
void Read() //读取公交线路并转换成图
{
memset(str, '#', sizeof(str));
gets(str);
int k = 0;
int i;
for (i = 0; i < strlen(str); i++)
{
if (str[i] >= '0' && str[i] <= '9')
{
int v = 0;
while (str[i] >= '0' && str[i] <= '9')
{
v = v * 10 + (str[i] - '0');
i++;
}
num[k++] = v;
//printf("%d\n", v);
i--;
}
}
//printf("%d\n", k);
for (i = 0; i < k; i++)
{
for (int j = i+1; j < k; j++)
{
map[num[i]][num[j]] = 1; //能连通的站台 初始化,意为做一次公交
}
}
}
void Dijkstra()
{
int i, j, k, vis[M];
int mincost, lowcost[M];
for (i = 1; i <= n; i++)
{
lowcost[i] = map[1][i];
vis[i] = 0;
}
for (i = 1; i <= n; i++)
{
k = -1;
mincost = INF;
for (j = 1; j <= n; j++)
{
if (!vis[j] && lowcost[j] < mincost)
{
k = j;
mincost = lowcost[j];
}
}
if (-1 == k)
{
break;
}
vis[k] = 1;
for (j = 1; j <= n; j++)
{
if (!vis[j] && map[k][j] + lowcost[k] < lowcost[j])
{
lowcost[j] = map[k][j] + lowcost[k];
}
}
}
if (INF == lowcost[n]) //无法到达时
{
printf("NO\n");
}
else
{
printf("%d\n", lowcost[n] - 1); //如果起点和终点在一条公交线输出0,故要计算的总和要减一
}
}
int main(void)
{
int k;
scanf("%d", &k);
while (k--)
{
int i;
scanf("%d %d", &m, &n);
getchar();
InitMap();
for (i = 0; i < m; i++)
{
Read();
}
//printMap();
Dijkstra();
}
return 0;
}