题目大意
题目链接
有一个电车网络,由
n
n
n个路口和轨道组成,每个路口有
m
m
m条轨道,每个路口有一个开关,默认指向第一条轨道,若要走另一个轨道则要切换开关状态。求从路口
a
a
a到路口
b
b
b最少需要切换多少次开关状态,如果到不了则输出
−
1
-1
−1。
输入格式
第一行三个数
n
、
a
、
b
n、a、b
n、a、b,表示有
n
n
n个路口,从路口
a
a
a到路口
b
b
b。
第
2
2
2~
n
+
1
n+1
n+1行,每行开头有一个数
K
i
K_i
Ki,表示接下来有多少条轨道,接下来
K
i
K_i
Ki个数字表示与之相连的轨道,开关默认指向第一条轨道
解题思路
不难发现这其实是一个最短路问题,因为题目只要求切换次数最少,并没有要求走的路线长度最短,因此每条路的权值就是开关的状态,开为0,关为1(要切换状态)。初始化只需要将每个路口第一条轨道的权值设为0,其他的设为1即可。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,s,t;
double g[1005][1005],x[1005],y[1005];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cin>>n>>s>>t;
memset(g,0x7f,sizeof(g));
for(int i=1;i<=n;i++)
{
int m;
cin>>m;
for(int j=1;j<=m;j++)
{
int x;
cin>>x;
if(j==1) g[i][x]=0;//初始化,第一条轨道不需要切换状态
else g[i][x]=1;
}
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(g[i][j]>g[i][k]+g[k][j])
g[i][j]=g[i][k]+g[k][j];
}//Floyed
if(g[s][t]<0x7f) cout<<g[s][t];
else cout<<-1;
return 0;
}