【蓝桥杯集训7】并查集专题(3 / 5)

目录

并查集模板

1249. 亲戚 - 并查集

837. 连通块中点的数量 - 并查集

240. 食物链 - 带权并查集

238. 银河英雄传说 - 


并查集模板

活动 - AcWing

int find(int x) //返回x的祖宗结点+状态压缩
{
    if(p[x]!=x) p[x]=find(p[x]);
    return p[x];
}
 
p[find(a)]=find(b); //合并操作 给a认个祖宗b
 
if(find(a)==find(b)) //a和b元素在同一个集合

for(int i=1;i<=n;i++) p[i]=i;
import java.util.*;

class Main
{
    static int N=100010;
    static int[] p=new int[N];
    
    public static int find(int x)
    {
        if(p[x]!=x) p[x]=find(p[x]); //如果不是祖宗,则向上查找
        return p[x];
    }
    
    public static void unite(int a,int b)
    {
        p[find(a)]=find(b); //给a认个祖宗b
    }
    
    public static void main(String[] args)
    {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt(),m=sc.nextInt();
        
        for(int i=1;i<=n;i++) p[i]=i;
        
        while(m-->0)
        {
            String s=sc.next();
            int a=sc.nextInt(),b=sc.nextInt();
            
            if(s.equals("M"))
            {
                if(find(a)!=find(b)) unite(a,b);
            }
            else 
            {
                if(find(a)==find(b)) System.out.println("Yes");
                else System.out.println("No");
            }
        }
    }
}

1249. 亲戚 - 并查集

1249. 亲戚 - AcWing题库

import java.util.*;
import java.io.*;

class Main
{
    static int N=20010;
    static int[] p=new int[N];
    
    public static int find(int x)
    {
        if(p[x]!=x) p[x]=find(p[x]);
        return p[x];
    }
    
    public static void main(String[] args)throws IOException
    {
        StreamTokenizer re=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter wt=new PrintWriter(new OutputStreamWriter(System.out));
        
        re.nextToken();
        int n=(int)re.nval;
        re.nextToken();
        int m=(int)re.nval;
        
        for(int i=1;i<=n;i++) p[i]=i;
        
        while(m-->0)
        {
            re.nextToken();
            int a=(int)re.nval;
            re.nextToken();
            int b=(int)re.nval;
            
            p[find(a)]=find(b);
        }
        
        re.nextToken();
        int q=(int)re.nval;
        while(q-->0)
        {
            re.nextToken();
            int a=(int)re.nval;
            re.nextToken();
            int b=(int)re.nval;
            
            if(find(a)==find(b)) wt.println("Yes");
            else wt.println("No");
        }
        wt.flush();
    }
}

837. 连通块中点的数量 - 并查集

活动 - AcWing

s[i]统计连通块内点的数量,i只有是祖宗节点才有意义

s[祖宗]的值就是该连通块中点的个数

import java.util.*;

class Main
{
    static int N=100010;
    static int[] p=new int[N],s=new int[N];
    
    public static int find(int x)
    {
        if(p[x]!=x) p[x]=find(p[x]);
        return p[x];
    }
    
    public static void unite(int a,int b)
    {
        p[find(a)]=find(b);
    }
    
    public static void main(String[] args)
    {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt(),m=sc.nextInt();
        for(int i=1;i<=n;i++)
        {
            p[i]=i;
            s[i]=1;
        }
        
        while(m-->0)
        {
            String t=sc.next();
            
            if(t.equals("C"))
            {
                int a=sc.nextInt(),b=sc.nextInt();
                if(find(a)!=find(b))
                {
                    s[find(b)]+=s[find(a)];
                    unite(a,b);
                }
            }
            else if(t.equals("Q1"))
            {
                int a=sc.nextInt(),b=sc.nextInt();
                if(find(a)==find(b)) System.out.println("Yes");
                else System.out.println("No");
            }
            else 
            {
                int x=sc.nextInt();
                System.out.println(s[find(x)]);
            }
        }
    }
}

240. 食物链 - 带权并查集

活动 - AcWing

题目:

思路:

 

238. 银河英雄传说 - 

活动 - AcWing

题目:

思路:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值