1、poj 1847 Tram 最短路
2、总结:用dijkstra做的,算出a到其它各个点要改向的次数。其它应该也可以。
题意: 有点难懂。n个结点,每个点可通向ki个相邻点,默认指向第一个相邻点,可以改变指向。求一条从A到B的路,使用最少改变路上点的指向的次数。
#include<iostream> #include<cstring> #include<cmath> #include<queue> #include<algorithm> #include<cstdio> #define max(a,b) a>b?a:b using namespace std; #define LL long long #define INF 0x3f3f3f3f const int N=110; int mapn[N][N],visit[N]; int change[N]; //改向的次数 int n,a,b; void Dijkstra() { int f; memset(visit,0,sizeof(visit)); for(int i=1;i<=n;i++){ change[i]=mapn[a][i]; } visit[a]=1; for(int i=2;i<=n;i++) { int minn=INF; f=-1; for(int j=1;j<=n;j++){ if(!visit[j]&&minn>change[j]){ minn=change[j]; f=j; //f存储连通分量中到a需改向数最少的点 } } if(f==-1)break; //找不到可通点就跳出 visit[f]=1; for(int j=1;j<=n;j++){ //更新change if(!visit[j]&&change[f]+mapn[f][j]<change[j]){ change[j]=change[f]+mapn[f][j]; } } } if(change[b]==INF)printf("-1 "); else printf("%d ",change[b]); } int main() { while(scanf("%d%d%d",&n,&a,&b)!=EOF) { memset(mapn,INF,sizeof(mapn)); for(int l=1;l<=n;l++) { int ki,m; scanf("%d",&ki); if(!ki)continue; //注意细节 scanf("%d",&m); mapn[l][m]=0; for(int i=2;i<=ki;i++){ scanf("%d",&m); mapn[l][m]=1; } } Dijkstra(); } return 0; }