2026/6/28 18:28:43
网站建设
项目流程
毕业生对于网站建设感受,淘金网站建设,wordpress 点击富强,建材企业网站推广方案题目背景
若某个家族人员过于庞大#xff0c;要判断两个是否是亲戚#xff0c;确实还很不容易#xff0c;现在给出某个亲戚关系图#xff0c;求任意给出的两个人是否具有亲戚关系。
题目描述
规定#xff1a;x 和 y 是亲戚#xff0c;y 和 z 是亲戚#xff0c;那么 x…题目背景若某个家族人员过于庞大要判断两个是否是亲戚确实还很不容易现在给出某个亲戚关系图求任意给出的两个人是否具有亲戚关系。题目描述规定x 和 y 是亲戚y 和 z 是亲戚那么 x 和 z 也是亲戚。如果 xy 是亲戚那么 x 的亲戚都是 y 的亲戚y 的亲戚也都是 x 的亲戚。输入格式第一行三个整数 n,m,pn,m,p≤5000分别表示有 n 个人m 个亲戚关系询问 p 对亲戚关系。以下 m 行每行两个数 MiMj1≤Mi, Mj≤n表示 Mi 和 Mj 具有亲戚关系。接下来 p 行每行两个数 Pi,Pj询问 Pi 和 Pj 是否具有亲戚关系。输出格式p 行每行一个Yes或No。表示第 i 个询问的答案为“具有”或“不具有”亲戚关系。输入输出样例输入 #1复制6 5 3 1 2 1 5 3 4 5 2 1 3 1 4 2 3 5 6输出 #1复制Yes Yes No一道相当接近模板题的并查集。如果我们注意到并查集是递归实现的并且具有如下形式int find(int n,vectorinta){ if(a[n]n)return n; //找到根节点 return a[n]find(a[n],a); //查询根节点 }这道题就会非常简单只需要先将每个a[i]赋值为i,然后对于每个关系使用re[i].firstre[i].second对应两个人int _minmin(re[i].first,re[i].second); int _maxmax(re[i].first,re[i].second); a[find(_max,a)]find(_min,a);就可以将关系联通注意我们每次更改的是关系的根节点随后对于查询只要找到两人对应的根节点即可。代码如下#includebits/stdc.h using namespace std; int find(int n,vectorinta){ if(a[n]n)return n; return a[n]find(a[n],a); } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr);cout.tie(nullptr); int n,m,p; cinnmp; vectorinta(n1,0); vectorpairint,intre(m1); stringstream ss; for(int i1;in;i)a[i]i; for(int i0;im;i){ cinre[i].firstre[i].second; int _minmin(re[i].first,re[i].second); int _maxmax(re[i].first,re[i].second); a[find(_max,a)]find(_min,a); } for(int i1;in;i)find(i,a); for(int i0;ip;i){ int q1,q2; cinq1q2; if(find(q1,a)find(q2,a))ssYes\n; else ssNo\n; } coutss.str(); return 0; }