poj1847 Tram 最短路Dijkstra
题目链接:http://poj.org/problem?id=1847
Dijkstra算法的模版应用
题意:给你N个点和起点终点,点与点有铁路,接下来的N行分别为点i的情况 第一个数字表示与该点连通的点的个数,接下来给该行的Ki个点,注意第一个所连的点为默认,通过的话不用改扳手,其余的点通过的话要改一次扳手,求从起点到终点改扳手的最小次数。
将不需要手动换方向转变为路径长度为0,
将需要手动换方向转变为路径长度为1即可
注意:
从第二行开始
每一行的第2个数为下一个默认的进入方向,所以不用手动换方向
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 using namespace std; 6 #define INF 100100100 7 #define maxn 110 8 int n,A,B; 9 int G[maxn][maxn]; 10 int dis[maxn*2]; 11 int s[maxn*2]; 12 void Dijkstra() 13 { 14 for(int i=1;i<=n;i++) 15 { 16 dis[i]=G[A][i]; 17 s[i]=0; 18 } 19 s[A]=1; 20 dis[A]=0; 21 for(int i=1;i<n;i++) 22 { 23 int Min=INF,u=A; 24 for(int j=1;j<=n;j++) 25 { 26 if(dis[j]<INF && s[j]==0 && Min>dis[j]) 27 { 28 u=j; 29 Min=dis[j]; 30 } 31 } 32 if(Min>INF) break; 33 s[u]=1; 34 35 for(int k=1;k<=n;k++) 36 { 37 if(s[k]==0 && G[u][k]<INF && dis[k]>dis[u]+G[u][k]) 38 dis[k]=dis[u]+G[u][k]; 39 } 40 } 41 } 42 int main() 43 { 44 while(scanf("%d%d%d",&n,&A,&B)!=EOF) 45 { 46 int num; 47 for(int i=1;i<=n;i++) 48 for(int j=1;j<=n;j++) 49 if(i==j) G[i][j]=0; 50 else G[i][j]=INF; 51 for(int i=1;i<=n;i++) 52 { 53 scanf("%d",&num); 54 int k,w; 55 for(int j=1;j<=num;j++) 56 { 57 scanf("%d",&k); 58 w=1; 59 if(j==1) w=0; 60 G[i][k]=w; 61 } 62 } 63 Dijkstra(); 64 if(dis[B]>=INF) 65 cout<<"-1"<<endl; 66 else 67 cout<<dis[B]<<endl; 68 } 69 return 0; 70 71 }