import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
public class E1_5_13 {
public static void main(String[]args){
//Solve dynamic connectivity problem on StdIn.
int N= StdIn.readInt();
WeightedQuickUFwithPath uf=new WeightedQuickUFwithPath(N);
while (!StdIn.isEmpty()){
int p=StdIn.readInt();
int q=StdIn.readInt();
if (uf.connected(p,q)){
uf.printid();
StdOut.println();
continue;
}
uf.union(p,q);
uf.printid();
StdOut.println(" | "+p+" "+q);
}
StdOut.println(uf.count()+" components");
}
}
import edu.princeton.cs.algs4.StdOut;
public class WeightedQuickUFwithPath {
private int[]id; //parent link(site indexed)
private int[]sz; //size of component for roots(site indexed) 只有根节点存储的是树的大小
private int count;//number of component
public WeightedQuickUFwithPath(int N){
count=N;
id=new int[N];
for (int i=0;i<N;i++) id[i]=i;
sz=new int[N];
for (int i=0;i<N;i++) sz[i]=1;
}
public int count(){
return count;
}
public boolean connected(int p,int q){
return find(p)==find(q);
}
public int find(int p){
//Find root.
int root=p;
while (root!=id[root])root=id[root];
while (id[p]!=root) {//有可能路径没有压缩
int next=id[p];//next node.
id[p] = root;
p=next;
}
return root;
}
public void union(int p,int q){
int i=find(p);
int j=find(q);
if (i==q)return;
//Make smaller root point to large one.
if (sz[i]<sz[j]){id[i]=j;sz[j]+=sz[i];}
else {id[j]=i;sz[i]+=sz[j];}
count--;
}
public void printid(){
for (int i=0;i<id.length;i++)
StdOut.print(id[i]+" ");
}
}