输入
7 12
7 6 7 5 7 4 7 3 5 4 4 2 3 7 3 4 3 1 2 6 2 1 1 4
输出
2
我们要找从n到1是否有路可循,并且求最短的路径。以上图为例子,从7开始进行查找。与7节点有关,且没有被遍历过的节点有
6,5,4,3这四个节点,标记这四个节点vis[i]=1;,并记下从7到它们的最短距离num[i]=1;
下一步,查找6节点,没有条件满足的节点;
下一步,查找5节点,没有条件满足的节点;
下一步,查找4节点,与4有关且未被遍历过的节点有2这一个节点;标记节点2,num[2]=2;
下一步,查找3节点,与3有关且未被遍历过的节点有1这一个节点;标记节点1,num[1]=2;
下一步,查找2节点,没有条件满足的节点;
下一步,查找1节点,没有条件满足的节点;
查找结束;
个人觉得BFS查找的过程类似于二叉树的层序遍历;
#include <bits/stdc++.h>
using namespace std;
int num[1001];//记录到n节点的最短距离
int Map[1001][1001];//记录节点的连通性
int vis[1001];//记录是否已遍历过该节点
int Now[1001];//存储已遍历的节点;
int n,m;
int BFS(int k)
{
memset(vis,0,sizeof(vis));
memset(Now,0,sizeof(Now));
memset(num,1061109567,sizeof(num));
int ss=0,ee=0;
Now[ss++]=k;
vis[k]=1;
num[k]=0;
while(ss>ee)
{
int now=Now[ee++];
for(int i=n;i>=1;i--)
{
if(Map[now][i]==1&&vis[i]==0)//当前节点与i节点连通&&没有遍历过
{
Now[ss++]=i;//将i节点存入
vis[i]=1;//标记已遍历过
num[i]=num[i]<num[now]?num[i]:num[now]+1;//若i节点此前到n节点的距离<当前节点到n节点的距离,num[i]不变;
} //否则,i节点到n节点的距离 = num[now]+1;
}
}
if(num[1]==1061109567)
printf("NO\n");
else
printf("%d\n",num[1]);
}
int main()
{
int u,v;
while(~scanf("%d %d",&n,&m))
{
memset(Map,0,sizeof(Map));
for(int i=0;i<m;i++)
{
scanf("%d %d",&u,&v);
Map[u][v]=1;
}
BFS(n);//从n开始查找;
}
}