第一次发题解
原题传送门
题意大概是这样的:
先给出三个数n,m,p,一共1…n个人,给定m组亲戚的关系(a,b),例如1和2是亲戚,1和3又是亲戚,那么2和3也是亲戚。最后给出p对人,问他们是不是亲戚,而亲戚的亲戚也是亲戚,所以此题用到并查集,合并题目中已知的亲戚关系。
以下先附上代码
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
//头文件
using namespace std;
int n,m,p,a,b;
int c,d,f[500001];
void init()
{
for(int i=1;i<=n;i++)
{
f[i]=i;
}
}
//赋值函数,先假定每个人的亲戚都是自己
int getf(int k)
{
if(f[k]==k)
{
return k;
}
else
{
return getf(f[k]);
}
}
//寻找函数,如果给定的a,b相同或者a,b有亲戚关系,那么返回出b的亲戚就是a,把a赋值给b,方便后来判断;
void merge(int x,int y)
{
int t1=getf(x);
int t2=getf(y);
if(t1!=t2)
{
f[t2]=t1;
}
return;
}
//合并函数,将两个亲戚合并,相当于把b的亲戚标上了a;
int main()
{
cin>>n>>m>>p;
//输入
init();
//调用函数
for(int i=1;i<=m;i++)
{
cin>>a>>b;
merge(a,b);
}
//输入亲戚关系,合并亲戚关系
for(int i=1;i<=p;i++)
{
cin>>c>>d;
//输入询问亲戚
c=getf(c);
d=getf(d);
依旧是调用寻找函数;
if(c==d)
{
cout<<"Yes"<<endl;
}
//寻找函数如果两个是亲戚,数字就相同,如果相同,就输出"Yes";
else
{
cout<<"No"<<endl;
}
//不一样就输出"No";
}
return 0;
}
现在一块一块来说
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<algorithm>
头文件,学C++和C的都知道…………
void init()
{
for(int i=1;i<=n;i++)
{
f[i]=i;
}
}
这是赋值的函数,假设一开始每个人都只有一个亲戚,那就是自己……
int getf(int k)
{
if(f[k]==k)
{
return k;
}
else
{
return getf(f[k]);
}
}
寻找亲戚的函数,如果给定了两个人是一样的,那么他们就都是自己的亲戚,就返回出一个值,如果不一样,且不知道是不是亲戚,那么就继续找出给定数的亲戚,直到找到他最终的亲戚,而在这个过程中,所有的被找过的数如果是最终亲戚的亲戚,那么就把最终亲戚的数赋值给过程中被找到的数,这样最后判断起来就十分方便……
void merge(int x,int y)
{
int t1=getf(x);
int t2=getf(y);
if(t1!=t2)
{
f[t2]=t1;
}
return;
}
这应该是最好理解的……给定两个数,找出每个数的最终的亲戚,如果不一样,那么把a的值赋给b,这样也是方便判断,如果一样,那就不用合并了,直接退出……
int main()
{
cin>>n>>m>>p;
init();
for(int i=1;i<=m;i++)
{
cin>>a>>b;
merge(a,b);
}
for(int i=1;i<=p;i++)
{
cin>>c>>d;
c=getf(c);
d=getf(d);
if(c==d)
{
cout<<"Yes"<<endl;
}
else
{
cout<<"No"<<endl;
}
}
return 0;
}
主函数,不用说了吧%%%……%%%
输入人数,亲戚关系数,要判断的亲戚关系数,再先调用函数赋值,输入亲戚关系,合并,再输入要判断的,如果两个数的最终亲戚是一样的,那么就是亲戚关系,否则就不是。