【Java每日一题,并查集】Ubiquitous Religions

简介: 【Java每日一题,并查集】Ubiquitous Religions

Introduction

当今世界上有许多不同的明星,你想知道你们学校的学生总共喜欢多少个不同的明星。

你知道你的大学里有n个学生(0 < n ≤ 50000),你问每个学生他们喜欢的明星是不可能的。此外,许多学生不好意思说出他们喜欢哪个明星。避免这些问题的一种方法是问m (0≤ m ≤ n(n-1)/2)对学生,问他们是否喜欢相同的明星(例如,他们可能知道他们是否观看同一场演出)。从这些数据中,你可能不知道每个人具体喜欢哪个明星,但你可以知道校园里最多有多少个不同的被喜欢的明星。你可以假设每个学生最喜欢的只有一个明星。


Input

输入由多组用例组成。每一种情况都以整数n和m作为的一行开始,接下来的m行分别由两个整数i和j组成,表示学生i和j喜欢相同的明星。学生被编号为1到n。输入的结束由一行指定,其中n = m = 0。


Output

对于每个测试用例,在单行上打印案例号(以1开头),后面跟着该大学学生所喜欢的不同明星的最大数量。


Sample

input

10 9
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 9
1 10
10 4
2 3
4 5
4 8
5 8
0 0

output

Case 1: 1
Case 2: 7

Solution

package week3;
import java.util.Scanner;
class UnionFind{
    private int[] id;
    private int[] sz;
    public int count;
    public UnionFind(int count){
        this.count=count;
        id=new int[count];
        sz=new int[count];
        for(int i=0;i<count;i++){
            id[i]=i;
            sz[i]=1;
        }
    }
    public int find(int x){
        if(id[x]!=x){
            id[x]=find(id[x]);
        }
        return id[x];
    }
    public void union(int x,int y){
        int xRoot=find(x);
        int yRoot=find(y);
        if(xRoot!=yRoot){
            if(sz[xRoot]>sz[yRoot]){
                id[yRoot]=xRoot;
                sz[xRoot]+=sz[yRoot];
            }else {
                id[xRoot]=id[yRoot];
                sz[yRoot]+=sz[xRoot];
            }
            count--;
        }
    }
}
public class Main {
    public static void main(String[] args) {
        Scanner s=new Scanner(System.in);
        int index=1;
        while(true){
            int n=s.nextInt();int m=s.nextInt();
            if(n==0&m==0){
                break;
            }
            UnionFind unionFind=new UnionFind(n);
            while (m--!=0){
                int x=s.nextInt();int y=s.nextInt();
                unionFind.union(x-1,y-1);
            }
            System.out.println("Case "+index+": "+unionFind.count);
            index++;
        }
    }
}

Experience

第一次使用并查集,也是学到了很多。刷题必会之一。

目录
打赏
0
0
0
0
8
分享
相关文章
Java数据结构之第十六章、并查集
Java数据结构之第十六章、并查集
151 0
【Java高阶数据结构】并查集-最小生成树
Java高阶数据结构 & 并查集 & 最小生成树 1. 并查集 1.1 并查集的原理 在一些应用问题中,我们常常会遇到一类问题 一开始是一个人 后来新增的人可能与这个人有关系,也可能与这个人无关系。 一个人与一个人有关系,这个人与另一个人也有关系,那么三人都有关系。 有关系的和没关系的之间是不同的类别。
189 0
用java写数据结构作业——7.2堆并查集哈夫曼树二
用java写数据结构作业——7.2堆并查集哈夫曼树二
java最简单的并查集(不想交集合)以及杭电1272
并查集要有的一些属性:value:表示当前值,指针:(不一定是指针)指向父节点。 还有一个属性number:表示该树存在的总个数。(也可以用深度表示)。我用小树插在大树上。
148 0
Java多线程基础
本文主要讲解多线程相关知识,分为两部分。第一部分涵盖多线程概念(并发与并行、进程与线程)、Java程序运行原理(JVM启动多线程特性)、实现多线程的两种方式(继承Thread类与实现Runnable接口)及其区别。第二部分涉及线程同步(同步锁的应用场景与代码示例)及线程间通信(wait()与notify()方法的使用)。通过多个Demo代码实例,深入浅出地解析多线程的核心知识点,帮助读者掌握其实现与应用技巧。
|
5月前
|
【Java并发】【线程池】带你从0-1入门线程池
欢迎来到我的技术博客!我是一名热爱编程的开发者,梦想是编写高端CRUD应用。2025年我正在沉淀中,博客更新速度加快,期待与你一起成长。 线程池是一种复用线程资源的机制,通过预先创建一定数量的线程并管理其生命周期,避免频繁创建/销毁线程带来的性能开销。它解决了线程创建成本高、资源耗尽风险、响应速度慢和任务执行缺乏管理等问题。
300 60
【Java并发】【线程池】带你从0-1入门线程池
|
3月前
|
【源码】【Java并发】从InheritableThreadLocal和TTL源码的角度来看父子线程传递
本文涉及InheritableThreadLocal和TTL,从源码的角度,分别分析它们是怎么实现父子线程传递的。建议先了解ThreadLocal。
145 4
【源码】【Java并发】从InheritableThreadLocal和TTL源码的角度来看父子线程传递
|
2月前
|
java 多线程异常处理
本文介绍了Java中ThreadGroup的异常处理机制,重点讲解UncaughtExceptionHandler的使用。通过示例代码展示了当线程的run()方法抛出未捕获异常时,JVM如何依次查找并调用线程的异常处理器、线程组的uncaughtException方法或默认异常处理器。文章还提供了具体代码和输出结果,帮助理解不同处理器的优先级与执行逻辑。
【高薪程序员必看】万字长文拆解Java并发编程!(9-2):并发工具-线程池
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的强力并发工具-线程池,废话不多说让我们直接开始。
102 0
Java网络编程,多线程,IO流综合小项目一一ChatBoxes
**项目介绍**:本项目实现了一个基于TCP协议的C/S架构控制台聊天室,支持局域网内多客户端同时聊天。用户需注册并登录,用户名唯一,密码格式为字母开头加纯数字。登录后可实时聊天,服务端负责验证用户信息并转发消息。 **项目亮点**: - **C/S架构**:客户端与服务端通过TCP连接通信。 - **多线程**:采用多线程处理多个客户端的并发请求,确保实时交互。 - **IO流**:使用BufferedReader和BufferedWriter进行数据传输,确保高效稳定的通信。 - **线程安全**:通过同步代码块和锁机制保证共享数据的安全性。
168 23

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问