题意:
有n个交叉点,每个交叉点有一个开关,开关能指向其它的交叉点。告诉你n个交叉点,初始位置,和目标位置。要你改变开关的总次数最小。
接下n行输入里,每行代码第i个交叉点,一行中,第一个代表,开关指向的另一个交叉点的个数,后面的代表开关能指向的交叉点的编号。(开关指向第一交叉
的编号为初始状态)
分析:这题看起来给路径没什么联系,其实,它还是个路径问题,只不过问题的方式不同,把开关指向的初始权值赋值为零,其他的赋值为1就行了。不需要考虑后面
开关改变,因为计算最短路径时,不会出现两次或多次经过同一点。
代码;
#include<stdio.h>
#include<string.h>
#define INF 1<<29
int visit[105],d[105];
int map[105][105];
void dijstra(int N,int beg,int end)
{
int i,j,k,dis;
memset(visit,0,sizeof(visit));
for(i=1;i<=N;i++)
d[i]=map[beg][i]; //从当前路径中获取路径
d[beg]=0,visit[beg]=1;
for(i=1;i<N;i++){
dis=INF;
k=beg; //从当前路径开始。
for(j=1;j<=N;j++)
if(!visit[j]&&d[j]<dis){
k=j;
dis=d[j];
}
visit[k]=1;
for(j=1;j<=N;j++){
if(!visit[j]&&map[k][j]<INF&&d[j]>d[k]+map[k][j]){
d[j]=map[k][j]+d[k];
}
}
}
if(d[end]<INF)
printf("%d\n",d[end]);
else printf("-1\n");
}
int main()
{
int i,j,k,t,a,b,N;
while(scanf("%d%d%d",&N,&a,&b)!=EOF){
for(i=1;i<=N;i++)
for(j=1;j<=N;j++)
map[i][j]=INF;
for(i=1;i<=N;i++)
{
scanf("%d",&k);
for(j=1;j<=k;j++){
scanf("%d",&t);
map[i][t]=(j==1?0:1);
}
}
dijstra(N,a,b);
}
return 0;
}