Disjoint set and poj 1611

本文介绍了一种并查集数据结构的实现方法,并通过解决POJ 1611问题来展示其应用。该实现包括查找、路径压缩和加权合并等关键操作。
package hello.test;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class DisjointSet {

	private final static int DEFAULT_SIZE = 10;
	private int[] parent;  // set array
	private int size;  // the size of the set array
	
	// constructor
	public DisjointSet() {
		this(DEFAULT_SIZE);
	}
	
	// constructor
	public DisjointSet(int size) {
		this.size = size;  // set number
		parent = new int[size + 1];
		
		for(int i = 0; i <= size; i++) {
			parent[i] = -1;  // every element of the set is one element set
		}
	}
	
	// get the ith element's value
	public int getParentNumber(int i) {
		if(i >= 0 && i < this.size + 1) 
			return parent[i];
		return -1;
	}
	
	// find the root of x
	public int find(int x) {
		if(parent[x] < 0) {
			return x;
		} else {
			return find(parent[x]);
		}
	}
	
	// find the root of i and compress the path
	public int collapsingFind(int i) {
		int j = 0;
		for(j = i; parent[j] > 0; j = parent[j]) {} // search the i's root j
		
		// compress the path from i to j, set all the node's root to j
		while(i != j) {
			int temp = parent[i];
			parent[i] = j;
			i = temp;
		}
		
		return j;  // return root
	}
	
	// union two set's roots
	public void union(int root1, int root2) {
		parent[root2] = root1;
	}
	
	// use root's number as rank to union two sets
	public int weightedUnion(int root1, int root2) {
		if(root1 == root2) return root1;
		
		int tmp = parent[root1] + parent[root2];  // the sum of two roots' node as the new root nodes
		if(parent[root2] < parent[root1]) {  // root2 has more nodes
			parent[root1] = root2;  // make root2 as the root of root1
			parent[root2] = tmp;  // new root nodes
			return root2;
		} else {  // root1 has more nodes
			parent[root2] = root1;  // make root1 as the root of root2
			parent[root1] = tmp;
			return root1;
		}
	}
	
	
	
	/**
	 * @param args
	 * @throws FileNotFoundException 
	 * solve poj 1611 The Suspects
	 */
	public static void main(String[] args) throws FileNotFoundException {
		long startTime = System.currentTimeMillis();   
		// TODO Auto-generated method stub
		@SuppressWarnings("resource")
		Scanner fin = new Scanner(new File("/home/will/myworld/workspace/HelloProject/src/hello/test/poj1611.txt"));
		int r1, r2;  // r1, r2 are roots number
		
		while(fin.hasNext()) {
			int n = fin.nextInt();
			int m = fin.nextInt();
			
			if(n == 0 && m == 0) break;
			
			DisjointSet ds = new DisjointSet(n);
			
			for (int i = 0; i < m; i++) {
				int k = fin.nextInt();
				int x = fin.nextInt();
				r1 = ds.collapsingFind(x);
				
				for(int j = 0; j < k - 1; j++) {
					int y = fin.nextInt();
					r2 = ds.collapsingFind(y);
					r1 = ds.weightedUnion(r1, r2);  // r1 becomes the new root, the left node will be union to r1
				}
			}
			
			System.out.println(-ds.getParentNumber(ds.collapsingFind(0)));
		}
		
		long endTime = System.currentTimeMillis();
		System.out.println("The run time is : " + (endTime - startTime) + " ms");
	}

}



 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值