算法18 《啊哈算法》第7章 擒贼先擒王井查集

看到题目先想到,直接建一个数组,然后读入关系,有关系的全部设定为一个数;但是存在一个问题:同一个点被更改两遍后关系就会断掉!
来看看怎么解吧。

题目

现在有10个强盗.

  • 1 号强盗与2 号强盗是同伙。
  • 3 号强盗与4 号强盗是同伙。
  • 5 号强盗与2 号强盗是同伙。
  • 4 号强盗与6 号强盗是同伙。
  • 2 号强盗与6 号强盗是同伙。
  • 8 号强盗与7 号强盗是同伙.
  • 9 号强盗与7 号强盗是同伙。
  • 1 号强盗与6 号强盗是同伙。
  • 2 号强盗与4 号强盗是同伙。
    有一点需要注意: 强盗同伙的同伙也是同伙。你能帮助警方查出有多少个独立的犯罪团
    伙吗?

代码

关键在递归查父节点的方法!

设关系数组两个数以小的为父节点,如果将大的数所在值不为该点自身的值,则步入该值(父节点),更改为新的父节点值。。

import java.util.Arrays;


public class ts {
    /*
    {{1,2},
    {3,4},
    {5,2},
    {4,6},
    {8,7},
    {2,6},
    {9,7},
    {1,6},
    {2,4}}
     */
    public static void main(String[] args) {
        int [][] relat=new int[][]//关系数组
                {{1,2},
                {3,4},
                {5,2},
                {4,6},
                {8,7},
                {2,6},
                {9,7},
                {1,6},
                {2,4}};
        int []x=new int[10];//存储节点

        for(int i=1;i<11;i++){
            x[i-1]=i;
        }
//        System.out.println(Arrays.toString(x));

        for(int i=0;i<9;i++){
            int a=relat[i][0];
            int b=relat[i][1];
            if (a>b){
                int am=getf(a,x);
                x[am-1]=x[b-1];//找到a的最高父节点,篡权
                x[a-1]=x[b-1];//更改a的父节点
            }
            else {
               int bm=getf(b,x);
               x[b-1]=x[a-1];
               x[bm-1] = x[a-1];
            }
            System.out.println(Arrays.toString(x));//打印聚类过程
        }

    }
    static int getf(int i, int x[]){//找到父节点
        if (x[i-1]!=i){
        i=x[x[i-1]];
        getf(i,x);
        }
        return i;
    }
}
原文地址:https://www.cnblogs.com/impw/p/15564289.html