luogu P1346 电车 最短路

显然结论

一个点不会经过了两次,一个阀门不会反复开关。第一条边为0,其余边为1。

 1 #include <cstdio>
 2 #include <queue>
 3 using namespace std;
 4 int head[120],dis[120],to[30000],nxt[30000],val[30000];
 5 bool vis[120];
 6 int cnt,s,t,n;
 7 
 8 struct pot
 9 {
10     int x,dis;
11     pot (int _x = 0,int _dis = 0) : x(_x),dis(_dis) {}
12     friend bool operator < (pot a,pot b)
13     {
14         return a.dis > b.dis;
15     }
16 };
17 priority_queue <pot> que;
18 void add(int x,int y,int v)
19 {
20     nxt[++cnt] = head[x];
21     to[cnt] = y;
22     head[x] = cnt;
23     val[cnt] = v;
24 }
25 void dijkstra()
26 {
27     for(int i=0; i<= n; i++) dis[i]=2e9;
28     que.push(pot(s,0));
29     dis[s]=0;
30     while(!que.empty())
31     {
32         pot now=que.top();
33         que.pop();
34         if(vis[now.x]) continue;
35         vis[now.x]=true;
36         for(int i = head[now.x]; i; i=nxt[i])
37         {
38             if(dis[to[i]]>dis[now.x]+val[i])
39             {
40                 dis[to[i]]=dis[now.x]+val[i];
41                 que.push(pot(to[i],dis[to[i]]));
42             }
43         }
44     }
45 }
46 int main()
47 {
48     scanf("%d%d%d",&n,&s,&t);
49     int tk,tmp;
50     for (int i = 1;i <= n;i++)
51     {
52         scanf("%d",&tk);
53         if (tk)
54         {
55             scanf("%d",&tmp); 
56             add(i,tmp,0);
57         }
58         for (int o = 2;o <= tk;o++)
59         {
60             scanf("%d",&tmp);
61             add(i,tmp,1);
62         }
63     }
64     dijkstra();
65     if (dis[t] == dis[0]) printf("-1
");
66     else printf("%d
",dis[t]);
67     return 0;
68 }
心之所动 且就随缘去吧
原文地址:https://www.cnblogs.com/iat14/p/11219203.html