Problem:
橋の取り壊し

水の国ウォーターデブンには n 個の都市があります。各都市は水に囲まれており、島国のようになっています。ウォーターデブンには m 本の橋があり、都市間の交通はそれらの橋によって行われ、全ての都市に行き来することができます。

最近、道路特定財源の見直しにより橋の維持費の削減が決定されました。全部の橋を維持することができなくなってしまい、いくつかの橋を取り壊すことになりました。そこで、ウォーターデブンはどの都市にでも行くことができるように橋を残しつつ、橋の維持費を最小化することが課題となりました。

都市の数、橋の数、各橋の維持費を入力とし、橋を利用してどの都市にも行けるようにしつつ、橋を取り壊した場合の維持費の最小値を出力するプログラムを作成してください。なお、橋の取り壊しには費用が掛からないものとします。ただし、各都市は 0 から n - 1 まで順番に番号が付けられているものとします。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロふたつの行で示されます。各データセットは以下の形式で与えられます。

n m
a1 b1 cost1
a2 b2 cost2
:
am bm costm

１行目に都市の数 n (2 ≤ n ≤ 100)、 橋の数 m (1 ≤ m ≤ 500) が与えられます。続く m 行に第 i の橋の情報が与えられます。ai, bi は橋がつないでいる都市の番号、costi (1 ≤ costi ≤ 1000) は橋にかかる維持費を表します。

Output

データセット毎に橋の維持費の合計を１行に出力します。

Sample Input

5 6
0 2 1
2 1 3
2 3 8
1 3 2
3 4 5
1 4 4
3 3
1 2 3
2 0 3
0 1 3
0 0

Output for the Sample Input

10
6

Solution in JAVA (judge verdict: Accepted)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while(true) {
			int n = sc.nextInt();
			int m = sc.nextInt();
			if (n == 0) {
				break;
			}
			Kruscal g = new Kruscal(n);
			for(int i=0;i<m;i++) {
				int a = sc.nextInt();
				int b = sc.nextInt();
				int c = sc.nextInt();
				g.addBidirectionalEdge(a,b,c);
			}
			System.out.println(g.minCost());
		}
	}

}

class Kruscal {
	int n;
	ArrayList<Edge> graph = new ArrayList<Edge>();

	public Kruscal(int n) {
		this.n = n;
	}

	public void addBidirectionalEdge(int u,int v,int cost) {
		graph.add(new Edge(cost,u,v));
	}

	public int minCost() {
		Collections.sort(graph);
		UnionFind uf = new UnionFind(n);
		int ans = 0;
		int connected = 1;
		for(int i=0;i<graph.size();i++) {
			Edge e = graph.get(i);
			if (!uf.isConnected(e.from, e.to)) {
				uf.union(e.from, e.to);
				connected++;
				ans+=e.cost;
				if (connected==n) {
					break;
				}
			}
		}
		return ans;
	}

	static class Edge implements Comparable<Edge>{
		int cost;
		int from;
		int to;
		public Edge(int cost,int from,int to) {
			this.cost = cost;
			this.from = from;
			this.to = to;
		}
		@Override
		public int compareTo(Edge o) {
			if (this.cost == o.cost) {
				return 0;
			}else if(this.cost > o.cost) {
				return 1;
			}else{
				return -1;
			}
		}

		public String toString() {
			return this.cost + "," + this.from + "," + this.to;
		}
	}

	static class UnionFind {
		private int[] data;
		public UnionFind(int size) {
			data = new int[size];
			Arrays.fill(data, -1);
		}
		public void union(int x,int y) {
			x = root(x);
			y = root(y);
			if (x!=y) {
				if (data[y] < data[x]) {
					int tmp = y;
					y = x;
					x = tmp;
				}
				data[x] += data[y];
				data[y] = x;
			}
		}
		public boolean isConnected(int x,int y) {
			return root(x)==root(y);
		}
		private int root(int x) {
			return data[x] < 0 ? x : (data[x] = root(data[x]));
		}
		public int size(int x) {
			return -data[root(x)];
		}
		public String toString() {
			return Arrays.toString(data);
		}
	}
}