Problem:
便利な町

来春卒業するAさんは、就職を機に引越しをすることにしました。就職する会社は、オフィスがいくつかの町にあって、日によって出勤するオフィスが違います。そこでAさんは,どこのオフィスに
行くにも時間の短い町に住もうと考えました。

そこであなたは、Aさんを助けるため、住むのに一番便利な町を探すことになりました。

町には 0 から始まる番号が振られており、町と町の間には道があります。それぞれの道に対して通勤時間が決まっています。Aさんがある町に住んでいる場合に、自分の町のオフィスまでの通勤時間は 0 とします。このときに全ての町までの通勤時間の総和を考えます。例えば、町と道の配置が上の図のようになっていて、Aさんが町1に住んだ場合には、それぞれの町までの通勤時間は

町 0 まで 80

町 1 まで 0

町 2 まで 20

町 3 まで 70

町 4 まで 90

となり、総和は 260 となります。

道の数と、全ての道の情報を入力とし、それぞれの町に住んだ場合の通勤時間の総和を計算し、それが最小となる町の番号と、そのときの通勤時間の総和を出力するプログラムを作成してください。ただし、通勤時間の総和が最小となる町が複数ある場合は、一番小さい町の番号及びその時の通勤時間の総和を出力してください。町の総数は 10 以下、道の総数は 45 以下とし、全ての道は双方向に移動でき、通勤時間は方向によって変わらないものとします。また、どの町からでもその他全ての町への 経路があるものとします。

Input

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

n
a1 b1 c1
a2 b2 c2
:
an bn cn

１行目に道の数 n (1 ≤ n ≤ 45) が与えられます。続く n 行に i 番目の道の情報が与えられます。
ai, bi (0 ≤ ai, bi ≤ 9) は i 番目の道がつないでいる町の番号、ci (0 ≤ ci ≤ 100) はその道の通勤時間を表します。

Output

データセット毎に、通勤時間の総和が最小になる町の番号及びその時の通勤時間の総和を空白区切りで１行に出力します。

Sample Input

6
0 1 80
1 2 20
0 2 60
2 3 50
3 4 60
1 4 90
2
0 1 1
1 2 1
0

Output for the Sample Input

2 240
1 2

Solution in JAVA (judge verdict: Accepted)


import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		new Main().run();
	}

	private void run() {
		Scanner scanner = new Scanner(System.in);
		while (true) {
			int n = scanner.nextInt();
			if (n == 0)
				break;

			int[][] num = new int[n][3];
			int size = 0;
			for (int i = 0; i < n; i++) {
				int a = scanner.nextInt();
				int b = scanner.nextInt();
				int c = scanner.nextInt();
				num[i][0] = a;
				num[i][1] = b;
				num[i][2] = c;
				size = Math.max(size, Math.max(a, b));
			}
			size++;
			int[][] cost = new int[size][size];
			for (int[] t : cost)
				Arrays.fill(t, 1 << 24);
			for (int i = 0; i < n; i++) {
				int a = num[i][0];
				int b = num[i][1];
				int c = num[i][2];
				cost[a][b] = c;
				cost[b][a] = c;

			}
			for (int i = 0; i < size; i++) {
				cost[i][i] = 0;

			}
			for (int i = 0; i < size; i++) {
				for (int j = 0; j < size; j++) {
					if(i==j)
						continue;
					for (int k = j + 1; k < size; k++) {
						cost[j][k] = Math.min(cost[j][k], cost[i][j]
								+ cost[i][k]);
						cost[k][j] = cost[j][k];

					}
				}
			}
			int ans = 0;
			int min = Integer.MAX_VALUE;
			for (int i = 0; i < size; i++) {
				int sum = 0;
				for (int j = 0; j < size; j++) {
					sum += cost[i][j];
				}
				if (sum < min) {
					min = sum;
					ans = i;
				}
			}
			System.out.println(ans + " " + min);
		}

	}

	private void slove(int x, int[][] cost) {
		Deque<Integer> deque = new ArrayDeque<Integer>();
		for (int i = 0; i < cost.length; i++) {
			if (cost[i][x] != 1 << 24) {
				deque.offer(i);
			}
		}
		cost[x][x] = 0;
		while (!deque.isEmpty()) {
			int pri = deque.poll();
			for (int i = 0; i < cost.length; i++) {
				if (pri == i)
					continue;
				if (cost[pri][i] != 1 << 24
						&& cost[x][i] > cost[pri][i] + cost[x][pri]) {
					cost[x][i] = cost[pri][i] + cost[x][pri];
					cost[i][x] = cost[pri][i] + cost[x][pri];
					if (!deque.contains(i))
						deque.offer(i);
				}
			}
		}

	}
}