传送门:http://poj.org/problem?id=1847
【分析】这个题目的意思就是有N个点,每个点会连接m个其它点,然后第N个点连接的第一个点是正常情况下不需要切换的路线,剩下连接的m-1个点是需要切换的,求A到B的最少切换次数。这题的思路是到第一个点(不需要切换的路线)的路径为0,到其它点的路径为1,然后求A到B的最短路径dist[B],为什么是这样子的呢?因为Dijkstra是会优先考虑较短的路径的,所以会先考虑0(不需要切换),若行不通则会考虑1(切换)。这样就可以求得最少切换次数了。
#include<iostream>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int map[100 + 5][100 + 5];
int dist[100 + 5];
int s[100 + 5];
const int M = 0x3f3f3f3f;
int n;
void Dijkstra(int v0);
int main()
{
while (scanf("%d", &n) != EOF)
{
int a, b;
scanf("%d%d", &a, &b);
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] = M;
}
}
for (int i = 1; i <= n; i++)
{
int m;
scanf("%d",&m);
int to;
for (int j = 1; j <= m; j++)
{
scanf("%d", &to);
if (j == 1)
map[i][to] = 0;
else
map[i][to] = 1;
}
}
Dijkstra(a);
if (dist[b] < M)
printf("%d\n", dist[b]);
else
printf("-1\n");
}
return 0;
}
void Dijkstra(int v0)
{
for (int i = 1; i <= n; i++)
{
s[i] = 0;
dist[i] = map[v0][i];
}
dist[v0] = 0;
s[v0] = 1;
for (int i = 1; i <= n; i++)
{
int min = M;
int k = v0;
for (int j = 1; j <= n; j++)
{
if (!s[j] && dist[j] < min)
{
min = dist[j];
k = j;
}
}
s[k] = 1;
for (int j = 1; j <= n; j++)
{
if (!s[j] && map[k][j] < M && map[k][j] + dist[k] < dist[j])
{
dist[j] = map[k][j] + dist[k];
}
}
}
}