POJ-1988 帶權並查集 Java

由於形成的不是樹,所以不能用向量法找關係。
用sum數組來維護i堆有幾個立方體,所以x移到y上去就會有r[fx] = sum[fy]表示根節點fx節點下有sum[fy]個立方體,再更新sum[fy] += sum[fx].

package 並查集;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main_POJ1988 {
	static int[] pre = new int[30005];
	static int[] r = new int[30005];  //表示x下面有個立方體(權值)
	static int[] sum = new int[30005];  //表示i堆有幾個立方體
	public static void main(String[] args) {
		InputReader1988 sc = new InputReader1988();
		int p = sc.nextInt();
		for(int i=1;i<=30000;i++) {
			pre[i] = i;
			r[i] = 0;
			sum[i] = 1;
		}
		for(int i=1;i<=p;i++) {
			String s = sc.next();
			if(s.equals("M")) {
				int x = sc.nextInt();
				int y = sc.nextInt();
				int fx = find(x);
				int fy = find(y);
				if(fx!=fy) {
					pre[fx] = fy;
					r[fx] = sum[fy];
					sum[fy] += sum[fx];
				}
			}else {
				int x = sc.nextInt();
				find(x); //移動時更新的是根節點的權值  可能未及時更新子節點權值
				System.out.println(r[x]);
			}
		}
	}
	public static int find(int x) {
		if(x==pre[x]) return x;
		int t = pre[x];
		pre[x] = find(pre[x]);
		r[x] += r[t];
		return pre[x];
	}
}
class InputReader1988 {
    BufferedReader buf;
    StringTokenizer tok;
    InputReader1988() {
        buf = new BufferedReader(new InputStreamReader(System.in));
    }
    boolean hasNext() {
        while(tok == null || !tok.hasMoreElements()) {
            try {
                tok = new StringTokenizer(buf.readLine());
            } 
            catch(Exception e) {
                return false;
            }
        }
        return true;
    }
    String next() {
        if(hasNext()) return tok.nextToken();
        return null;
    }
    int nextInt() {
        return Integer.parseInt(next());
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章