众所周知,图的权值通常定义为a->b的长度,但是这道题要改变一下定义。
因为不难发现,在同一条路线上并不需要换乘,也就是说如果将权值定义为这两点是否需要换乘,是的话就是1,不是就是0,然后在此基础上运行一遍最短路模板就能得出答案。
但是我们会发现这样去定义权值,图画出来的权值统统都是0。
所以可以再改变一下定义,定义两点到达所需要的乘车次数,也就是说同一条路线上,任意两点的权值都是1(注意是有向图)。
你以为这样就AC了?,这道题还有一个潜在的问题,输入并没有明确输入数量,所以要用while来输入,输入到换行的时候结束,但是测评机里面最后是没有换行的,也就是2 1 3 5,而非我们需要的2 1 3 5\n,这也是为什么本地输入全对,提交全错的问题之一。
AC代码
#include <bits/stdc++.h>
using namespace std;
const int MAXN=500+1;
const int MAX=INT_MAX>>1;
int e[MAXN][MAXN],n,m,a[MAXN];
int main(){
scanf("%d%d",&m,&n);
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
e[i][j]=MAX;
for(int i=1;i<=n;++i)
e[i][i]=0;
for(int p=1;p<=m;++p){
int cnt=0;
scanf("%d",&a[++cnt]);
char ch=getchar();
while(ch==' '){
scanf("%d",&a[++cnt]);
ch= getchar();
}
for(int i=1;i<=cnt;++i)
for(int j=i+1;j<=cnt;++j)
e[a[i]][a[j]]=1;
}
for(int k=1;k<=n;++k)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
e[i][j]= min(e[i][j],e[i][k]+e[k][j]);
if(e[1][n]==MAX)cout<<"NO";
else cout<<e[1][n]-1;
return 0;
}
因为定义的是乘车次数,需要的输出是换成次数,所以输出乘车次数减一。