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=; int mapn[N][N],visit[N];
int change[N]; //改向的次数
int n,a,b; void Dijkstra()
{
int f;
memset(visit,,sizeof(visit));
for(int i=;i<=n;i++){
change[i]=mapn[a][i];
}
visit[a]=; for(int i=;i<=n;i++)
{
int minn=INF;
f=-;
for(int j=;j<=n;j++){
if(!visit[j]&&minn>change[j]){
minn=change[j];
f=j; //f存储连通分量中到a需改向数最少的点
}
}
if(f==-)break; //找不到可通点就跳出
visit[f]=; for(int j=;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\n");
else printf("%d\n",change[b]);
} int main()
{
while(scanf("%d%d%d",&n,&a,&b)!=EOF)
{
memset(mapn,INF,sizeof(mapn));
for(int l=;l<=n;l++)
{
int ki,m;
scanf("%d",&ki);
if(!ki)continue; //注意细节
scanf("%d",&m);
mapn[l][m]=;
for(int i=;i<=ki;i++){
scanf("%d",&m);
mapn[l][m]=;
}
} Dijkstra();
} return ;
}