package com.xjj.Ah;
import java.util.Scanner;
/*-----树--并查集--犯罪独立数及头目---
* 1. 并查集,通过一维数组来实现,其本质是维护一个森林。
* 刚开始,森林的每个节点都是孤立的,之后一些条件...逐渐将这些并成一颗树
* 合并:就是找根节点的过程, 遵守 “靠左” 及 “擒贼先擒王” 的原则
* 还需注意,必须求其根节点,中间节点不能说明问题
*
* 2.擒贼先擒王: 1 2(1为2的BOSS), 5 2(5为2的BOSS) 时让 "5为1的BOSS"
* 3.如果a[i] = i不变,则表明其是根节点
*
* */
public class Ah_7_4 {
static private int N = 0;
static private int M = 0;
int[] a = new int[N+1]; //强盗人数
//递归找根节点的函数,也就是找犯罪团伙的最高领导人
public int getf(int m){
if (a[m] == m)
return m;
else {
//压缩路径,每次函数返回的时候带回最高领导人的编号
a[m] = getf(a[m]);
return a[m];
}
}
//合并两子集的函数
public void merge(int left, int right){
int tl = getf(left);
int tr = getf(right);
//判断两子集是否在同一集合中,即同根节点,同团伙
if (tl != tr)
//“靠左原则”,左边变成右边的BOSS,
a[tr] = tl;
}
public static void main(String[] args) {
System.out.println("输入强盗的人数n及搜索到的信息m:");
Scanner scanner = new Scanner(System.in);
N = scanner.nextInt(); //强盗数
M = scanner.nextInt(); //消息数
Ah_7_4 ah = new Ah_7_4();
int sum = 0;
//初始化,自己对自己的下标
for(int i = 1; i <= N; i++)
ah.a[i] = i;
for(int i = 1; i <= M; i++){
int b = scanner.nextInt();
int c = scanner.nextInt();
ah.merge(b, c);
}
System.out.println("犯罪头目为: ");
for(int i = 1; i <= N; i++){
//如果a[i]不变,则表明其是根节点
if (ah.a[i] == i) {
System.out.print(ah.a[i] + " ");
sum++;
}
}
System.out.println();
System.out.println("有独立犯罪团伙 : " + sum);
}
}
树--并查集--犯罪独立数及头目
最新推荐文章于 2021-09-27 14:12:14 发布
本文介绍了一种使用一维数组实现的并查集算法,详细解释了如何通过该算法确定犯罪团伙之间的关系,并实现了合并不同团伙的功能。文章还提供了一个完整的Java程序示例,展示了如何寻找根节点以及如何应用‘擒贼先擒王’的原则。
摘要由CSDN通过智能技术生成