问题 C: 数据结构基础14-关系网络

题目描述

有 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

样例输入 Copy
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
样例输出 Copy
2
提示

【问题分析】
本题是求最优值问题。显然,如果 x 和 y 本身就认识,则答案是 0;否则,答案至少为 1。如果 x 和 y 通过 z 这一个人就间接认识,那么答案是 1,可以通过穷举 z 来实现;否则,答案至少为2。……如此做下去,一定能找到答案(最大为n-2)。这种算法叫作“宽度优先搜索”,简称“宽搜”,具体实现需要通过一个队列在实现过程中扩展到所有人。
把 x 加入队列并设置为队头元素,设 q[x][1]=0,从队头开始进行宽搜,穷举邻接矩阵的第 x 行,看 x 认识谁(判断 a[x][j]=1),认识的人(j)全部依次入队,并且 q[j][1]++。如果出现了 y,则输出 q[f][1]-1,结束搜索;否则,取出队头元素继续宽搜。

递归循环中有y>=ans的判断是一定要有的,不然数据多了空间复杂度会很高,时间会很容易超限,虽然不会影响输出的正确结果

#include<iostream>
using namespace std;
int a[101][101];
int ans = 100000;
int n, p, q;
void find(int x, int y)
{
	if (x == q)
	{
		ans = min(ans, y - 1);
	}
	if (y >= ans)
	{
		return;
	}
	for (int i = 1; i <= n; i++)
	{
		if (a[x][i] == 1)
		{
			a[x][i] = 0;
			find(i, y + 1);
			a[x][i] = 1;
		}
	}
}
int main()
{
	cin >> n >> p >> q;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			cin >> a[i][j];
		}
	}
	find(p, 0);
	cout << ans << endl;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值