下面我们来看并查集的实现。 int pre[1000]; 这个数组,记录了每个大侠的上级是谁。大侠们从1或者0开始编号(依据题意而定),pre[15]=3就表示15号大侠的上级是3号大侠。如果一个人的上级就是他自己,那说明他就是掌门人了,查找到此为止。也有孤家寡人自成一派的,比如欧阳锋,那么他的上级就是他自己。每个人都只认自己的上级。比如胡青牛同学只知道自己的上级是杨左使。张无忌是谁?不认识!要想知道自己的掌门是谁,只能一级级查上去。
privateint[] parent; // parent[i] = parent of i privatebyte[] rank; // rank[i] = rank of subtree rooted at i (never more than 31) privateint count; // number of components
/** * Initializes an empty union-find data structure with * {@code n} elements {@code 0} through {@code n-1}. * Initially, each elements is in its own set. */ publicUF(int n) { if (n < 0) thrownew IllegalArgumentException(); count = n; parent = newint[n]; rank = newbyte[n]; for (int i = 0; i < n; i++) { parent[i] = i; rank[i] = 0; } }
//Returns the canonical element of the set containing element {@code p}. publicintfind(int p) { validate(p); while (p != parent[p]) { parent[p] = parent[parent[p]]; // path compression by halving p = parent[p]; } return p; }
//Returns the number of sets. publicintcount() { return count; } //Returns true if the two elements are in the same set. @Deprecated publicbooleanconnected(int p, int q) { return find(p) == find(q); } /** * Merges the set containing element {@code p} with the * the set containing element {@code q}. */ publicvoidunion(int p, int q) { int rootP = find(p); int rootQ = find(q); if (rootP == rootQ) return;
// make root of smaller rank point to root of larger rank if (rank[rootP] < rank[rootQ]) parent[rootP] = rootQ; elseif (rank[rootP] > rank[rootQ]) parent[rootQ] = rootP; else { parent[rootQ] = rootP; rank[rootP]++; } count--; }
// validate that p is a valid index privatevoidvalidate(int p) { int n = parent.length; if (p < 0 || p >= n) { thrownew IllegalArgumentException("index " + p + " is not between 0 and " + (n-1)); } }
/** * Reads an integer {@code n} and a sequence of pairs of integers * (between {@code 0} and {@code n-1}) from standard input, where each integer * in the pair represents some element; * if the elements are in different sets, merge the two sets * and print the pair to standard output. */ publicstaticvoidmain(String[] args) { int n = StdIn.readInt(); UF uf = new UF(n); while (!StdIn.isEmpty()) { int p = StdIn.readInt(); int q = StdIn.readInt(); if (uf.find(p) == uf.find(q)) continue; uf.union(p, q); StdOut.println(p + " " + q); } StdOut.println(uf.count() + " components"); } }