加权路径压缩并查集实现

package algs4;

import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;

import java.io.FileInputStream;
import java.io.InputStream;

/**
 * 并查集
 * Created by blank on 2015-10-15 下午8:56.
 */
public class UF {

    public static void main(String[] args) throws Exception {
        InputStream input = new FileInputStream(Constants.PATH + "largeUF.txt");
        System.setIn(input);
        int N = StdIn.readInt();
        UF uf = new UF(N);
        while (N-- > 0) {
            int p = StdIn.readInt();
            int q = StdIn.readInt();
            if (uf.connected(p, q)) continue;
            uf.union(p, q);
//            StdOut.println(p + " " + q);
        }
        StdOut.println(uf.getCount() + " components");

    }

    private int[] parent;
    private byte[] rank;
    private int count;

    public UF(int n) {
        count = n;
        parent = new int[n];
        rank = new byte[n];
        for (int i = 0; i < n; i++) {
            parent[i] = i;
            rank[i] = 0;
        }
    }

    public int getCount() {
        return count;
    }

    public boolean connected(int p, int q) {
        return find(p) == find(q);
    }

    private int find(int p) {
        while (p != parent[p]) {
            parent[p] = parent[parent[p]];
            p = parent[p];
        }
        return p;
    }

    public void union(int p, int q) {
        int rootP = find(p);
        int rootQ = find(q);
        if (rootP == rootQ) {
            return;
        }
        if (rank[rootP] < rank[rootQ]) {
            parent[rootP] = rootQ;
        } else if (rank[rootP] > rank[rootQ]) {
            parent[rootQ] = rootP;
        } else {
            parent[rootP] = rootQ;
            rank[rootQ]++;
        }
        count--;
    }

}
时间: 2024-10-17 00:19:33

加权路径压缩并查集实现的相关文章

计蒜客 444 / xtuoj 1024 京东的物流路径(并查集+离线lca)

题意:一颗树,定义一条路径的权值等于路径的边权之和,需要求这颗树所有路径中权值的最大值 思路: 考虑到路径权值与点权的最值有关,而最值的问题通常可以通过排序就行处理,于是想到先把点权排序. 容易看出如果某条路径的权值是通过某个点算出的最小 ,那么肯定这条路径肯定不会经过权值更小的点,于是有了两种处理思路 1.按点权从小到大删点,对于即将删除的点,比他权值小的点已经被删去了,所以只要在当前状态的森林里找一条最长路径乘以次点权就可以更新答案 2.按点权从大到小加点,显然新加进来的点权值最小,当前树里

POJ 2421 Constructing Roads (Kruskal算法+压缩路径并查集 )

Constructing Roads Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 19884   Accepted: 8315 Description There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each

UVALive 6910 Cutting Tree(并查集应用)

总体来说,这个题给的时间比较长,样例也是比较弱的,别的方法也能做出来. 我第一次使用的是不合并路径的并查集,几乎是一种暴力,花了600多MS,感觉还是不太好的,发现AC的人很多都在300MS之内的过得. 看到他们的做法后,我知道了这个题比较好的做法. 逆向思维的并查集,因为这里只有去边操作,完全可以离线计算,把删边当成加边,然后逆序输出答案即可. 但是,这个却有一个坑,很坑,只有第一次删除的时候,我们才对他进行操作,加边的时候也只能在第一次删除的时候加.当时因为这里,十分困惑-- 这是我无路径压

HDU1272:小希的迷宫(并查集)

小希的迷宫 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 67049    Accepted Submission(s): 21037 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1272 Description: 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也

并查集 路径压缩

使用并查集查找时,如果查找次数很多,那么使用朴素版的查找方式肯定要超时.比如,有一百万个元素,每次都从第一百万个开始找,这样一次运算就是10^6,如果程序要求查找个一千万次,这样下来就是10^13,肯定要出问题的. 这是朴素查找的代码,适合数据量不大的情况: int findx(int x){ int r=x; while(parent[r] !=r) r=parent[r]; return r;} 下面是采用路径压缩的方法查找元素: int find(int x) //查找x元素所在的集合,回

poj 2513 Colored Sticks(欧拉回路 并查集 路径压缩 字典树)(困难)

Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 32545   Accepted: 8585 Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a st

hdu 1558 线段相交+并查集路径压缩

Segment set Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3457    Accepted Submission(s): 1290 Problem Description A segment and all segments which are connected with it compose a segment set.

并查集(2)-按秩合并和路径压缩

在上面一讲是并查集(1)-判断无向图是否存在环. 我们使用了并查集的两个操作: union() 和 find() // find 的原始实现 int find(int parent[], int i) { if (parent[i] == -1) return i; return find(parent, parent[i]); } // union()的原始实现 void Union(int parent[], int x, int y) { int xset = find(parent, x

hdu 1856 并查集(路径压缩)

hdu 1856 More is better 简单的并查集,用到了路径压缩 题意:找出节点数最多的连通分支,并输出该节点数. 思路:统计每个连通分支的节点数(利用并查集构建图时进行路径压缩,用一个与根节点下标对应的sum数组记录节点数),比较后得出最大值. 1 #include<cstdio> 2 #include<cstring> 3 4 int set[10000000 + 50]; 5 int sum[10000000 + 50]; 6 bool visit[1000000