//方法一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;
}
洛谷P1551 亲戚 题解
于 2024-04-18 21:21:30 首次发布