Union_Find_set

import java.util.Scanner;

/** 
 * ClassName:UnionFindSet <br/> 
 * Function: 并查集. <br/> 
 * Reason:   并查集. <br/> 
 * Date:     2013年10月14日 下午4:37:42 <br/> 
 * @author   
 * @version   
 * @since    JDK 1.6 
 * @see       
 */
public class UnionFindSet {
	
	private int[] father;		
	private int[] rank;
	
	/**
	 * 
	 * make_set:<br />
	 * 把每一个元素初始化为一个集合 
	 * 初始化后每一个元素的父节点是它本身
	 *
	 * @author zhangzhaoyu
	 */
	public void make_set() {
		
		for (int i=0; i<father.length; i++) {
			father[i] = i;
			rank[i] = 0;
		}
	}

	/**
	 * 
	 * find_set:<br />
	 * 查找一个元素所在的集合,其重点是找到这个元素所在的
	 * 结合的祖先
	 *
	 * @author zhangzhaoyu
	 * @param x
	 * 要查找的元素
	 * @return
	 * 查找到祖先
	 */
	public int find_set_recursion(int x) {
		
		if (x != father[x]) {
			father[x] = find_set(father[x]);
		}
		return father[x];
	}
	
	/**
	 * 
	 * find_set:<br />
	 * 将查找路径的所有节点都指向根节点 
	 *
	 * @author zhangzhaoyu
	 * @param x
	 * @return
	 */
	public int find_set(int x) {
		
		int k, root;
		root = x;
		
		while (root != father[root]) {
			root = father[root];
		}
		
		while (x != root) {
			k = father[x];
			father[x] = root;
			x= k;
		}
		return x;
	}
	
	public void union(int x, int y) {
		
		x = find_set_recursion(x);
		y = find_set_recursion(y);
		if (x == y) {
			return ;
		}
		if (rank[x] > rank[y]) {
			father[y] = x;
		} else if (rank[x] < rank[y]) {
			father[x] = y;
		} else {
			rank[y]++;
			father[x] = y;
		}
		
	}
	
	/**
	 * 
	 * printSet:<br />
	 * 打印各个数据集
	 *
	 * @author zhangzhaoyu
	 */
	public void print_set() {
		
		for (int i=1; i<father.length; i++) {
			if (father[i] == i) {
				System.out.print("[ ");
				for (int j=1; j<father.length; j++) {
					int z = find_set(j);
					if (z == i) {
						System.out.print(j + " ");
					}
				}
				System.out.println(" ]");
			}
		}
	}
	
	public void readData() {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int m = in.nextInt();
		father = new int[n+1];
		rank = new int[n+1];
		
		make_set();
		
		for (int i=1; i<=m; i++) {
			int a = in.nextInt();
			int b = in.nextInt();
			int x = find_set_recursion(a);
			int y = find_set_recursion(b);
			union(x, y);
		}
		
		print_set();
		
	}
	
	public static void main(String[] args) {
		new UnionFindSet().readData();
	}

}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值