题目地址:​​点击打开链接​

思路:建图很巧妙,和学长讨论过,我还以为只能用BFS做呢,没想到最短路径也能做,还有用DP做的,说2种建图方式,第二种不太明白

(1)一条路线上的站点和它后面的站点建单向边,权值为1,跑个最短路结果减1就行

(2)

要注意的一点就是,站点表示的数字可以是2,3位数,刚开始runerror了,就是因为把所有站点都当成一位数了

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>

using namespace std;

const int zui = 10000000;
const int maxn = 510;
int m,n;
char a[2000];
int map1[maxn][maxn];
int b[maxn];
int lowdist[maxn];
int visit[maxn];

void Dijkstra()
{
memset(visit,0,sizeof(visit));
int i,j,k;
for(i=1; i<=n; i++)
{
lowdist[i] = map1[1][i];
}
visit[1] = 1;
for(i=1; i<n; i++)
{
int min2 = zui;
k = 0;
for(j=1; j<=n; j++)
{
if(!visit[j] && lowdist[j] < min2)
{
min2 = lowdist[j];
k = j;
}
}
if(k == 0)
break;
visit[k] = 1;
for(j=1; j<=n; j++)
{
if(!visit[j] && lowdist[k] + map1[k][j] < lowdist[j])
{
lowdist[j] = lowdist[k] + map1[k][j];
}
}
}
}

int main()
{
int i,j;
int k;
scanf("%d",&k);
while(k--)
{
scanf("%d%d",&m,&n);
for(i=1; i<=n; i++)
{
for(j=1; j<=n; j++)
{
map1[i][j] = zui;
}
map1[i][i] = 1;
}
getchar();
for(i=1; i<=m; i++)
{
gets(a);
int len = strlen(a);
int p = 0;
int l,sum = 0;
for(j=0; j<len; j++)
{
if(a[j] == ' ')
{
b[p++] = sum;
sum = 0;
}
else
{
sum = sum * 10 + a[j] - '0';
}
}
b[p++] = sum;
for(j=0; j<p; j++)
{
for(l=j+1; l<p; l++)
{
map1[b[j]][b[l]] = 1;
}
}
}
Dijkstra();
if(lowdist[n] != zui)
printf("%d\n",lowdist[n] - 1);
else
printf("NO\n");
}
return 0;
}