链接:https://vjudge.net/problem/POJ-1847
题意:
就是有n个交叉点,就当做有n个点就行,然后这些点和其他点有些路径,每个点是一个开关,开关只能有一个方向走一条路,而第一个数就是默认的开关指向,不用旋转。
思路:
DIjkstra,对于每个位置的第一个方向 权值为0,其他的权值为1,不同的的权值为INF。
对起始点用最短路即可。
代码:
#include <iostream>
#include <memory.h>
#include <string>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <algorithm>
#include <map>
#include <queue>
#include <math.h>
using namespace std;
const int MAXN = 100+10;
const int INF = 1e9;
int Map[MAXN][MAXN];
int Vis[MAXN];
int Dis[MAXN];
int n,s,e;
int main()
{
int num,w;
scanf("%d%d%d",&n,&s,&e);
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;
for (int i = 1;i<=n;i++)
{
scanf("%d",&num);
for (int j = 0;j<num;j++)
{
scanf("%d",&w);
if (j == 0)
Map[i][w] = 0;
else
Map[i][w] = 1;
}
}
for (int i = 1;i<=n;i++)
Dis[i] = Map[s][i];
Vis[s] = 1;
for (int i = 1;i<=n;i++)
{
int w = -1,small = INF;
for (int j = 1;j<=n;j++)
{
if (Vis[j] == 0&&Dis[j] < small)
{
w = j;
small = Dis[j];
}
}
Vis[w] = 1;
if (w == -1||w == e)
break;
for (int j = 1;j<=n;j++)
{
if (Vis[j] == 0&&Dis[j] > Dis[w] + Map[w][j])
Dis[j] = Dis[w] + Map[w][j];
}
}
if (Dis[e] >= INF)
printf("-1\n");
else
printf("%d\n",Dis[e]);
return 0;
}