显然结论
一个点不会经过了两次,一个阀门不会反复开关。第一条边为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 }