クラスカル法をJavaで書く.

蟻本見ながら書いた.二つくらいの問題でちゃんと動いたのでたぶん合ってると思う.

コード

static class Kruskal {
	int n;
	List<int[]> edges;

	public Kruskal(int n) {
		this.n = n;
		edges = new ArrayList<int[]>();
	}

	void addEdge(int u, int v, int cost) {
		edges.add(new int[] { u, v, cost });
	}

	List<int[]> getEdges() {
		Collections.sort(edges, new Comparator<int[]>() {
			@Override
			public int compare(int[] o1, int[] o2) {
				return o1[2] - o2[2];
			}
		});
		UnionFind uf = new UnionFind(n);
		List<int[]> result = new ArrayList<int[]>();
		for (int[] edge : edges) {
			if (!uf.isSame(edge[0], edge[1])) {
				uf.unite(edge[0], edge[1]);
				result.add(edge);
			}
		}
		return result;
	}
}

static class UnionFind {
	int[] par;
	int[] rank;

	public UnionFind(int n) {
		par = new int[n];
		rank = new int[n];
		for (int i = 0; i < n; ++i) {
			par[i] = i;
			rank[i] = 0;
		}
	}

	int find(int x) {
		return (par[x] == x) ? x : (par[x] = find(par[x]));
	}

	void unite(int x, int y) {
		x = find(x);
		y = find(y);
		if (x == y)
			return;
		if (rank[x] < rank[y]) {
			par[x] = y;
		} else {
			par[y] = x;
			if (rank[x] == rank[y])
				++rank[x];
		}
	}

	boolean isSame(int x, int y) {
		return find(x) == find(y);
	}
}

使い方

・SPOJ 3188 "Minimum Spanning Tree"

public static void main(String[] args) throws Exception{
	Kruskal k = new Kruskal(next());
	for(int m = next();m-->0;){
		k.addEdge(next()-1, next()-1, next());
	}
	long sum = 0;
	for(int[] i : k.getEdges()){
		sum += i[2];
	}
	System.out.println(sum);
}

Topcoder SRM 492 hard "TimeTravellingSalesman"
bidirectedで書いてるけど関係ないかも.

public long determineCost(int N, String[] roads) {
	Kruskal k = new Kruskal(N);
	for(String str : concat(roads).split(" ")){
		String[] strs = str.split(",");
		int u = new Integer(strs[0]), v = new Integer(strs[1]), c = new Integer(strs[2]);
		k.addEdge(u, v, c);
		k.addEdge(v, u, c);
	}
	long r = 0;
	List<int[]> edges = k.getEdges();
	if(edges.size() != N - 1){
		return -1;
	}
	for(int[] is : edges){
		r += is[2];
	}
	return r;
}