洛谷P1551 亲戚 题解

//方法一bfs
//用人数为点,亲戚关系为边建无向图
//判断是否为亲戚,是通过bfs从起点是否能搜索到终点为依据
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
vector<int>w[5005];//存图
int n,m,p,vis[5005];//vis是标记已搜索点,避免无线搜索
int main(){
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n>>m>>p;
    //存图
    for(int i=1;i<=m;i++){
    	int a,b;
    	cin>>a>>b;
    	w[a].push_back(b);
    	w[b].push_back(a);
	}
	//判断亲戚关系
	while(p--){
		memset(vis,0,sizeof(vis));//把vis复原
		int a,b,find=0;//find标记是否为亲戚
		cin>>a>>b;
		queue<int>q;
		q.push(a);
		vis[a]=1;
		//bfs
		while(!q.empty()){
			int u=q.front();
			q.pop();
			//终止条件
			if(u==b){
				cout<<"Yes"<<endl;
				find=1;
				break;
			}
			//遍历所有可能点
			for(int i=0;i<w[u].size();i++){
				//如果未被遍历,就推入队列中,并标记为以遍历
				if(!vis[w[u][i]]){
					q.push(w[u][i]);
					vis[w[u][i]]=1;
				}
			}
		}
		//输出结果
		if(!find)cout<<"No"<<endl;
	}
	return 0;
}
//方法二并查集
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
int fa[5005],n,m,q;//用fa数组储存父亲节点
//查找x的父亲节点
int find(int x){
	if(x==fa[x])return x;
	else{
		fa[x]=find(fa[x]);//路径压缩
		return fa[x];
	}
}
//更新函数
void unionn(int a,int b){
	int fa_a=find(a);
	int fa_b=find(b);
	fa[fa_a]=fa_b;//更新a的父亲节点
}
int main(){
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n>>m>>q;
    for(int i=1;i<=n;i++)fa[i]=i;//初始化
    for(int i=1;i<=m;i++){
    	int a,b;
    	cin>>a>>b;
    	unionn(a,b);
	}
    while(q--){
    	int a,b;
    	cin>>a>>b;
    	//如果公共祖先相同cout‘yes’,否则cout‘no’
    	if(find(a)==find(b))cout<<"Yes"<<endl;
    	else cout<<"No"<<endl;
	}
	return 0;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值