简体   繁体   English

为什么我的联合查找不交集集算法不能通过所有测试用例?

[英]Why is my Union Find Disjoint Sets algo for this problem not passing all test cases?

Sample input: 输入样例:

1
3 2
1 2
2 3

First line = # of test cases 第一行=测试用例数

First number of second line = number of people 第二行的第一人数=人数

Second number of second line = number of friendships, F 第二行的第二个数字=友谊数F

Following F lines = the friendships 遵循F线=友谊

Output would be the size of the largest friend group. 输出将是最大的朋友组的大小。

So, sample output for that input would be 3. ([1, 2, 3]) 因此,该输入的样本输出为3。[[1、2、3])

My solution: 我的解决方案:

import java.util.Scanner;
import java.util.HashMap;
import java.util.Collections;

public class Main {

    public static void main (String args[]) {
        Scanner reader = new Scanner(System.in);
        int tests = reader.nextInt();
        for (int i = 0; i < tests; i++) {
            int numcitizens = reader.nextInt();
            // the input is 1-indexed so I create the parent array as such
            int[] parent = new int[numcitizens + 1];
            for (int j = 0; j < (numcitizens + 1); j++) {
                parent[j] = j;
            }
            int[] rank = new int[numcitizens + 1];
            int numpairs = reader.nextInt();
            for (int j = 0; j < numpairs; j++) {
                int A = reader.nextInt();
                int B = reader.nextInt();
                union(A, B, parent, rank);
            }
            HashMap<Integer, Integer> histo = new HashMap<Integer, Integer>();
            for (int j = 1; j < parent.length; j++) {
                int root = parent[j];
                if (!histo.containsKey(root)) {
                    histo.put(root, 1);
                }
                else {
                    histo.put(root, histo.get(root) + 1);
                }

            }
            int max = Collections.max(histo.values());
            System.out.println(max);
        }
    }

    // UFDS find
    static int find(int x, int[] parent) {

        if (parent[x]!= x) {
            parent[x] = find(parent[x], parent);
        }

        return parent[x];
    }

    // UFDS union
    static void union(int x, int y, int[] parent, int[] rank) {
        int xRoot = find(x, parent);
        int yRoot = find(y, parent);

        if (xRoot == yRoot) {
            return;
        }
        else {
            if (rank[xRoot] < rank[yRoot]) {
                parent[xRoot] = yRoot;
            }

            else if (rank[yRoot] < rank[xRoot]) {
                parent[yRoot] = xRoot;
            }

            else {
                parent[yRoot] = xRoot;
                for (int i = 0; i < parent.length; i++) {
                    if (parent[i] == yRoot) {
                        parent[i] = xRoot;
                    }
                }
                rank[xRoot] = rank[xRoot] + 1;
            }
        }
    }
}

It works for the sample input, but when passing it through an online judge system that runs it through hundreds of test cases, it tells me wrong output. 它适用于示例输入,但是当通过在线判断系统(通过数百个测试用例运行它)时,它会告诉我错误的输出。 Not sure where my error might be? 不知道我的错误可能在哪里? Seems like a simple UFDS problem to me. 在我看来,这是一个简单的UFDS问题。

The for loop you put in union ruins the performance. 您放入union的for循环会破坏性能。 Just take it out. 拿出来

In the histogram loop, you need int root = find(j,parent); 在直方图循环中,您需要int root = find(j,parent);

Your code throws an exception when numcitizens is zero. numcitizens为零时,您的代码将引发异常。

Fix that stuff and your code will work, I think. 修复这些问题,您的代码将正常运行。

Here are a couple extra hints: 这里有一些额外的提示:

  • I always union by size instead of union by rank. 我总是按大小合并而不是按等级合并。 It has the same complexity, and the size is often useful. 它具有相同的复杂性,并且大小通常很有用。 In this case you wouldn't need to build the histogram because you'd have the size of every root right there. 在这种情况下,您将不需要构建直方图,因为您将拥有每个根的大小。

  • I use a single int[] array for the data structure. 我使用单个int[]数组作为数据结构。 If a value v is >=0, then it's a root set with that size (0 means there's no set or empty set at that index). 如果值v > = 0,则它是具有该大小的根集(0表示该索引处没有集或空集)。 Otherwise ~v is a link to the parent set. 否则, 〜v是到父集的链接。 I recently used that structure in this answer: Algorithm: use union find to count number of islands 我最近在此答案中使用了该结构: 算法:使用联合查找来计算岛的数量

The number of friends each person has is not the parent array.Rank of each person is the height of tree representing by the set ie the number of friend that person have. 每个人拥有的朋友数量不是parent数组。每个人的排名是由集合表示的树的高度,即该人拥有的朋友数量。 so use root=rank[j]+1 in the for loop for counting the max friends. 因此请在for循环中使用root=rank[j]+1来计算最大朋友数。

int max=Integer.MAX_VALUE;
for(int r:rank){
    max=Math.max(max,r+1);
}
System.out.println(max);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 用于实现不交集(联合查找)的数据结构是什么? - What data structure to use for the implementation of disjoint sets(union find)? 为什么我的字符数组的就地递归代码不适用于所有测试用例? 我的代码有什么问题 - why my code of inplace recursion of character array is not working for all the test cases? is there any problem with my code 当所有测试用例运行时,我的测试用例失败。 但是单独跑的时候通过 - My test cases fail when all test cases are run. But passing when ran individually Hashmap 代码未通过所有测试用例 - Hashmap code not passing all the test cases HackerRank - No Prefix Set 未通过所有测试用例 - HackerRank - No Prefix Set not passing all the test cases AlgoExpert:验证子序列,不通过所有测试用例 - AlgoExpert: Validate Subsequence, not passing all test cases 为什么时间限制超过问题在一个代码中显示,而在另一个代码中传递测试用例? - why Time Limit exceed problem is showing in one code while passing test cases in other? 在 Valid Anagram 程序中未通过所有测试用例 - in Valid Anagram program not passing all test cases Union + Find算法(不相交集)的应用 - Application of Union+Find algorithm(Disjoint Set) 用于对两个不相交集执行并运算的数据结构 - Data structure used to perform the union operation on two disjoint sets
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM