题目描述
有 n 个人,他们的编号为 1~n,其中有一些人相互认识,现在 x 想要认识 y,可以通过他所认识的人来认识更多的人(如果 a 认识 b,b 认识 c,那么 a 可以通过 b 来认识 c),求出 x 最少需要通过多少人才能认识 y。
输入
第 1 行 3 个整数 n、x、y,2≤n≤100;
接下来的 n 行是一个 n×n 的邻接矩阵,
a[i][j]=1 表示 i 认识 j,a[i][j]=0 表示不认识。
保证 i=j 时,a[i][j]=0,并且 a[i][j]=a[j][i]。
输出
一行一个整数,表示 x 认识 y 最少需要通过的人数。数据保证 x 一定能认识 y
样例输入
5 1 5
0 1 0 0 0
1 0 1 1 0
0 1 0 1 0
0 1 1 0 1
0 0 0 1 0
样例输出
2
问题分析
- 创建一个bool型的visited数组,用来记录结点是否被访问,并创建队列(一个二维数组queue[ ][ ]),其中queue[ ][0]存放每一层的顶点,queue [ ] [1]存放层数。
- 从队头1开始访问,并进行入队操作,并将其设置为访问状态,开始遍历。
- (以下重复操作知道队列为空)
3.1 队头顶点w出队
3.2 依次检查w的所有邻接点v,若结点未被访问,则将其置于访问状态,同时将其入队。
代码实现
#include<iostream>
#include<cstring> //memset需要这个库
int queue[105][2];//其中queue[ ][0]存放每一层的顶点,queue [ ] [1]存放层数。
int a[105][105]; //邻接矩阵
bool visited[105];//结点是否访问
using namespace std;
int main()
{
memset(visited,true,sizeof(visited)); //设置为未访问的状态
int n,x,y;
cin>>n>>x>>y;
int front=1,rear=1;//表示队列的队头队尾
queue[front][0]=x,queue[front][1]=0;//先取出1作为起点并进行搜索
visited[x]=false;//设置为为访问状态
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cin>>a[i][j];
}
}
while(front<=rear)//队列是否还有元素
{
int tmp=queue[front][0];
if(tmp==y)
{
cout<<queue[front][1]-1<<endl;
return 0;
}
for(int i=1;i<=n;i++)
{
if(a[tmp][i]==1&&visited[i])
{
++rear;
queue[rear][0]=i;
queue[rear][1]=queue[front][1]+1;
visited[i]=false;
}
}
front++;
}
return 0;
}