【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

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

相关文章
|
存储 Java
Java数据结构之第十六章、并查集
Java数据结构之第十六章、并查集
108 0
|
存储 算法 Java
【Java高阶数据结构】并查集-最小生成树
Java高阶数据结构 & 并查集 & 最小生成树 1. 并查集 1.1 并查集的原理 在一些应用问题中,我们常常会遇到一类问题 一开始是一个人 后来新增的人可能与这个人有关系,也可能与这个人无关系。 一个人与一个人有关系,这个人与另一个人也有关系,那么三人都有关系。 有关系的和没关系的之间是不同的类别。
114 0
|
存储 Java
用java写数据结构作业——7.2堆并查集哈夫曼树二
用java写数据结构作业——7.2堆并查集哈夫曼树二
|
Java
java最简单的并查集(不想交集合)以及杭电1272
并查集要有的一些属性:value:表示当前值,指针:(不一定是指针)指向父节点。 还有一个属性number:表示该树存在的总个数。(也可以用深度表示)。我用小树插在大树上。
120 0
|
20天前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
11天前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
5天前
|
监控 Java 开发者
深入理解Java中的线程池实现原理及其性能优化####
本文旨在揭示Java中线程池的核心工作机制,通过剖析其背后的设计思想与实现细节,为读者提供一份详尽的线程池性能优化指南。不同于传统的技术教程,本文将采用一种互动式探索的方式,带领大家从理论到实践,逐步揭开线程池高效管理线程资源的奥秘。无论你是Java并发编程的初学者,还是寻求性能调优技巧的资深开发者,都能在本文中找到有价值的内容。 ####
|
10天前
|
安全 Java 开发者
Java中的多线程编程:从基础到实践
本文深入探讨了Java多线程编程的核心概念和实践技巧,旨在帮助读者理解多线程的工作原理,掌握线程的创建、管理和同步机制。通过具体示例和最佳实践,本文展示了如何在Java应用中有效地利用多线程技术,提高程序性能和响应速度。
39 1
|
18天前
|
安全 Java 开发者
Java 多线程并发控制:深入理解与实战应用
《Java多线程并发控制:深入理解与实战应用》一书详细解析了Java多线程编程的核心概念、并发控制技术及其实战技巧,适合Java开发者深入学习和实践参考。
40 6
|
19天前
|
Java 开发者
Java多线程编程的艺术与实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的技术文档,本文以实战为导向,通过生动的实例和详尽的代码解析,引领读者领略多线程编程的魅力,掌握其在提升应用性能、优化资源利用方面的关键作用。无论你是Java初学者还是有一定经验的开发者,本文都将为你打开多线程编程的新视角。 ####