链接: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 "); else printf("%d ",Dis[e]); return 0; }