首页 > 其他分享 >并查集

并查集

时间:2023-06-18 21:35:28浏览次数:40  
标签:int 查集 namespace init Maxsize find

并查集模板:

 

#include<bits/stdc++.h>
#define Maxsize 100005//只需要改这里就可以 
using namespace std;
int fa[Maxsize],rankk[Maxsize];
inline void init(int n)//初始化 
{
    for(int i=1;i<=n;++i){
        fa[i]=i;
        rankk[i]=1;
    }
}
int find(int x)//查找 
{
    if(x==fa[x])
    {
      return x;    
    }
    else
    { 
       fa[x]=find(fa[x]);//找到根节点 
       return fa[x];    //返回根节点
    
    }
      
}
inline void merge(int i,int j)//合并 
{
    int x=find(i),y=find(j);//先找到根节点的秩 
    if(rankk[x]<=rankk[y]){
        fa[x]=y;
    }
    else{
        fa[y]=x;
    }
    if(rankk[x]==rankk[y] && x!=y){
        rankk[y]++;
    }
}

P3367

#include<bits/stdc++.h>
#define Maxsize 100005//只需要改这里就可以 
using namespace std;
int fa[Maxsize],rankk[Maxsize];
inline void init(int n)//初始化 
{
    for(int i=1;i<=n;++i){
        fa[i]=i;
        rankk[i]=1;
    }
}
int find(int x)//查找 
{
    if(x==fa[x])
    {
      return x;    
    }
    else
    { 
       fa[x]=find(fa[x]);//找到根节点 
       return fa[x];    //返回根节点
    
    }
      
}
inline void merge(int i,int j)//合并 
{
    int x=find(i),y=find(j);//先找到根节点的秩 
    if(rankk[x]<=rankk[y]){
        fa[x]=y;
    }
    else{
        fa[y]=x;
    }
    if(rankk[x]==rankk[y] && x!=y){
        rankk[y]++;
    }
}
int main()
{
    int n,m;
    cin>>n>>m;
    init(n);
    for(int i=0;i<m;i++)
    {
        int z,x,y;
        cin>>z>>x>>y;
        if(z==1)
        {
            merge(x,y);
        }
        else
        {
            if(find(x)==find(y))
                cout<<"Y"<<endl;
            else
                cout<<"N"<<endl;
        }
        
    }
    
    return 0;
    
}

 

P1551

#include<bits/stdc++.h>
#define Maxsize 5005//只需要改这里就可以 
using namespace std;
int fa[Maxsize],rankk[Maxsize];
inline void init(int n)//初始化 
{
    for(int i=1;i<=n;++i){
        fa[i]=i;
        rankk[i]=1;
    }
}
int find(int x)//查找 
{
    if(x==fa[x])
    {
      return x;    
    }
    else
    { 
       fa[x]=find(fa[x]);//找到根节点 
       return fa[x];    //返回根节点
      //以下结果一样 
      //return find(fa[x]);
      //fa[x]=find(fa[x]);
    
    }
      
}
inline void merge(int i,int j)//合并 
{
    int x=find(i),y=find(j);//先找到根节点的秩 
    if(rankk[x]<=rankk[y]){
        fa[x]=y;
    }
    else{
        fa[y]=x;
    }
    if(rankk[x]==rankk[y] && x!=y){
        rankk[y]++;
    }
}
int main()
{
    int n,m,p;
    cin>>n>>m>>p;
    init(n);
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        merge(x,y);
    }
    for(int i=0;i<p;i++)
    {
        int x,y;
        cin>>x>>y;
        if(find(x)==find(y))
        {
            cout<<"Yes"<<endl;
        }
        else 
        {
            cout<<"No"<<endl;
        }
    }
    return 0;
    
}

 

标签:int,查集,namespace,init,Maxsize,find
From: https://www.cnblogs.com/zcbiao/p/17489767.html

相关文章

  • HDU 3277 Marriage Match III(并查集+二分+最大流)
    题意:和HDU3081一样的题意,只不过多了一个条件,每个女孩除了能选自己喜欢的男生之外,还能选不超过K个自己不喜欢的男生,问游戏最多能进行几轮思路:除了选喜欢的,还能选任意K个不喜欢的,怎么建图呢?一开始我想每个女孩连喜欢的男孩,而且选K个不喜欢的男孩也连边,可是这K个要怎么确定呢?这种显然......
  • HDU 3081 Marriage Match II(二分+并查集+最大流)
    题意:有N个女孩要与N个男孩玩配对游戏.每个女孩有一个可选男孩的集合(即该女孩可以选自己集合中的任意一个男孩作为该轮的搭档).然后从第一轮开始,每个女孩都要和一个不同的男孩配对.如果第一轮N个女孩都配对成功,那么就开始第二轮配对,女孩依然从自己的备选男孩集合中选择,但是不能......
  • HDU - 2473 (并查集+设立虚父节点(马甲))
    涉及到并查集的删除操作,比较复杂,可以利用虚设父节点的方法:例如:有n个节点,进行m次操作.首先将0~n-1的节点的父节点设置为i+n,n~2n+1的节点的父节点设置为本身,有m次操作,所以要用到m个虚节点,例如0,1,2,3,4,5的父节点为7,8,9,10,11,把他们插入2的集合,所以他们的根节点都为8,当把2从集合......
  • 数据结构与算法分析(Java语言描述)(24)—— 并查集的路径压缩
    packagecom.dataStructure.union_find;//我们的第五版Union-FindpublicclassUnionFind5{//rank[i]表示以i为根的集合所表示的树的层数//在后续的代码中,我们并不会维护rank的语意,也就是rank的值在路径压缩的过程中,有可能不在是树的层数值//这也是......
  • POJ2236(并查集)
    题目:http://poj.org/problem?id=2236 题意:给定n个点的坐标,然后选出其中的一些点出来,问在这些点中的指定的两点是否连通。#include<iostream>#include<string.h>#include<stdio.h>usingnamespacestd;constintN=1005;structPoint{intx,y;};Pointp[N];i......
  • UVALive - 6889[并查集+STL]
    题目链接:https://vjudge.net/contest/301219#problem/F 解题思路:枚举每个矩形的时候,看它是否需要和其他人合并只需要查看它的外形边框是否又被标记,这个可以直接用离散化,然后set存一下每个矩形四个格子,就可以用log(n)找到合并的矩形,然后后并查集并一下就好了。#include<bits/std......
  • hdu 3038(种类并查集)
    题目大意:有n次询问,给出a到b区间的总和,问这n次给出的总和中有几次是和前面已近给出的是矛盾的解题思路:这道题第一次接触很难往并查集方向去思考。这里使用的并查集很灵活,不仅仅要记录其父亲节点,同时还要记录该节点到父亲节点的总和。在更新时,[l,r]要变成[l-1,r],比如有区间[1,2],[3,4......
  • poj 2985(并查集+线段树求K大数)
    解题思路:这道题并查集很容易,合并时找到父节点就直接加上去就ok了。关键是如何求K大数,我一直在想用线段树怎么写,一开始想如果直接记录数的大小那肯定是没戏了,借鉴了一下别人的思路:区间[a,b]记录的是所有的数里面,等于a,a+1,a+2,......,b-1,b的个数。看到这里就应该明白了,这里线段树的用法......
  • hdu 2473(并查集+删除操作)
    解题思路:这道题有并查集的删除操作,如果直接对这一棵树进行删除节点操作肯定是很困难的。所以可以建立虚拟节点,只要有一个节点要被删除,就直接把它投影到虚拟节点上,即用这个虚拟节点来代替我们要删除的节点。这样我们就不需要用对已有的树形结构进行改动了。这个想法我在DragonBalls......
  • hdu 3635(并查集+路径压缩变形)
    解题思路:这道题想了我好久,因为我把城市的编号一起考虑进去了,结果想了好久都没A,最后看了别人的题解居然都没有考虑到城市的编号,不考虑城市编号的问题的话就是一个很水的并查集了。#include<iostream>#include<cstdio>#include<cstring>usingnamespacestd;constintMAXN=1000......