洛谷P1346 电车【最短路】

题目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\n");
70     else printf("%d\n", d[b]);
71     return 0;
72 }

 

posted @ 2019-07-01 19:37  wyboooo  阅读(160)  评论(0编辑  收藏  举报