题目:https://www.luogu.org/problemnew/show/P1346
题意:n个路口,每个路口有好几条轨道,默认指向给出的第一个路口。
如果要换到另外的轨道去需要按一次开关。问从a到b最少需要几次开关。
思路:可以把默认的路口的轨道权值设为0,其他的权值都是1,不通的权值都是inf。
然后跑一遍最短路。注意-1.
1 #include<cstdio> 2 #include<cstdlib> 3 #include<map> 4 #include<set> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<cmath> 9 #include<stack> 10 #include<queue> 11 #include<iostream> 12 13 #define inf 0x3f3f3f3f 14 using namespace std; 15 typedef long long LL; 16 typedef pair<int, int> pr; 17 18 int n, a, b; 19 const int maxn = 105; 20 int g[maxn][maxn]; 21 bool vis[maxn]; 22 int d[maxn]; 23 void dijkstra(int st) 24 { 25 memset(d, 0x3f, sizeof(d)); 26 d[st] = 0; 27 vis[st] = true; 28 for(int i = 1; i <= n; i++){ 29 if(i != st)d[i] = g[st][i]; 30 } 31 for(int t = 1; t < n; t++){ 32 int min = inf, minid; 33 for(int i = 1; i <= n; i++){ 34 if(!vis[i] && d[i] < min){ 35 min = d[i]; 36 minid = i; 37 } 38 } 39 40 vis[minid] = true; 41 for(int i = 1; i <= n; i++){ 42 if(d[i] > min + g[minid][i]){ 43 d[i] = min + g[minid][i]; 44 } 45 } 46 } 47 48 return; 49 } 50 51 int main() 52 { 53 scanf("%d%d%d", &n, &a, &b); 54 memset(g, 0x3f, sizeof(g)); 55 for(int i = 1; i <= n; i++){ 56 int k, to; 57 scanf("%d", &k); 58 if(k){ 59 scanf("%d", &to); 60 g[i][to] = 0; 61 } 62 for(int j = 1; j < k; j++){ 63 scanf("%d", &to); 64 g[i][to] = 1; 65 } 66 } 67 68 dijkstra(a); 69 if(d[b] > 1e9)printf("-1 "); 70 else printf("%d ", d[b]); 71 return 0; 72 }