并查集和dfs有点相像,都是但是个人认为并查集偏向找点,最终目的是归为点(祖先)而dfs偏向找层,层层递归,找到我们需要的数据。前者偏向结果,后者偏向过程。
并查集:
不了解并查集的话可以做一做pta中"部落"那个题,用到了并查集知识,属于比较基础的。并查集基本结构:
void init(){//p[x]代表x的父节点,初始时可以先将节点的父节点指向自己。
for(ll i=0;i<nl;i++){
p[i]=i;
}
}
ll find(ll x){//找祖先节点,即父节点指向自己的点
if(x==p[x]){
return x;
}else{
return p[x]=find(p[x]);
}
}
void findl(ll x,ll y){//此函数是find的函数的补充,用来满足题目提出的特殊要求,将两个祖先不同的点建立亲属关系(可以参考pta中"红色警报"https://editor.csdn.net/md/?articleId=115874152和"家庭房产"https://editor.csdn.net/md/?articleId=115706351,家庭房产更特别一点)
ll fa=find(x);
ll fb=find(y);
if(fa!=fb){
p[fa]=fb;
}
}
dfs:
不了解dfs可以做一下pta中"功夫传人"和"深入虎穴",都是层层搜索然后找到想要的答案,这两个题也可以用并查集操作,但是会超时,这也说明dfs比并查集快一些。dfs基本结构:
void dfs(ll x,ll y){//一般需要两个参数
if(v[x].size()==0){//根据条件记录需要的数据,一般结合vector数组一起使用。
if(y>=num){
num=y;
ad=x;
}
}else{
for(ll i=0;i<v[x].size();i++){//层层递归,注意:这里的i要现用现定义,因为递归中需要用到i,出递归后i的值可能会改变,影响循环。
dfs(v[x][i],y+1);
}
}
}