Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"fmt"
	)

var scanner = bufio.NewScanner(os.Stdin)

const INF = 0x7FFFFFFF

func main() {
	for scanner.Scan() {
		n, _ := strconv.Atoi(scanner.Text())
		if n == 0 {
			break
		}
		matrix := make([][]int, 10)
		for i := range matrix {
			matrix[i] = make([]int, 10)
		}
		for i := range matrix {
			for j := range matrix[i] {
				if i == j {
					matrix[i][j] = 0
				} else {
					matrix[i][j] = INF
				}
			}
		}
		num := 0
		for i := 0; i < n; i++ {
			scanner.Scan()
			buf := strings.Split(scanner.Text(), " ")
			from, _ := strconv.Atoi(buf[0])
			to, _ := strconv.Atoi(buf[1])
			cost, _ := strconv.Atoi(buf[2])
			if num < from {
				num = from
			}
			if num < to {
				num = to
			}
			matrix[from][to] = cost
			matrix[to][from] = cost
		}
		num++
		for i := 0; i < num; i++ {
			for j := 0; j < num; j++ {
				for k := 0; k < num; k++ {
					if matrix[j][i]+matrix[i][k] < matrix[j][k] {
						matrix[j][k] = matrix[j][i]+matrix[i][k]
					}
				}
			}
		}
		ans, sum := 0, INF
		for i := 0; i < num; i++ {
			now := 0
			for j := 0; j < num; j++ {
				now += matrix[i][j]
			}
			if sum > now {
				sum = now
				ans = i
			}
		}
		fmt.Println(ans, sum)
	}
}

C++: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <cstring>
#include <assert.h>

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n)  FOR(i,0,n)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define ALL(s) (s).begin(),(s).end()
#define ITE(c) typeof((c).begin())

#define clr(a) memset((a),0,sizeof(a))
#define nclr(a) memset((a),-1,sizeof(a))
#define pb push_back
#define INRANGE(x,s,e) ((s)<=(x) && (x)<(e))
#define MP(a,b) make_pair((a),(b))

#define INF 1<<24
#define MAX_V 999

using namespace std;

struct Node{
	int cost;
	int depart;
	int arrival;
};

vector<Node> dat;
vector<int> cost;

void dijkstra(int s){
	int pos;
	queue<int> q;
	int t;
	cost.at(s)=0;
	
	for(vector<Node>::iterator i=dat.begin();i!=dat.end();i++){
		if((*i).depart==s){
			q.push((*i).arrival);
			cost.at((*i).arrival)=(*i).cost;
		}
	}
	
	while(!q.empty()){
		
		pos=q.front();
		q.pop();
		
		for(vector<Node>::iterator i=dat.begin();i!=dat.end();i++){			if((*i).depart==pos){
				if(cost.at((*i).arrival)==INF){
					q.push((*i).arrival);
				}
				if(cost.at((*i).arrival)>(*i).cost+cost.at(pos)){
					cost.at((*i).arrival)=(*i).cost+cost.at(pos);
				}
			}
		}
		bool f=true;
		rep(i,cost.size()){
			if(cost.at(i)==INF){
				f=false;
			}
		}
		if(f){
			break;
		}
	}
}

int main(){
	int a, b, c, num;
	Node t;
	int n;
	while(cin>>n,n){
		num=0;
		dat.clear();
		cost.clear();
		rep(i,n){
			cin>>a>>b>>c;
			t.depart =a;
			t.cost   =c;
			t.arrival=b;
			dat.push_back(t);
			t.depart =b;
			t.cost   =c;
			t.arrival=a;
			dat.push_back(t);
			num=max(num,max(a,b));
		}
		rep(k,n+1){
			cost.push_back(INF);
		}
		int mini=-1, mCost=INF;
		rep(i,num+1){
			int sum=0;
			cost.clear();
			rep(k,num+1){
				cost.push_back(INF);
			}
			dijkstra(i);
			rep(j,num+1){
				sum+=cost.at(j);
			}
			if(sum<mCost){
				mCost=sum;
				mini=i;
			}
		}
		cout<<mini<<" "<<mCost<<endl;
	}
	return 0;
}

C++: // 2014/06/16 Tazoe

#include <iostream>
using namespace std;

const int INF = 1000000000;

int main()
{
	while(true){
		int n;
		cin >> n;

		if(n==0)
			break;

		int T[10][10];
		for(int i=0; i<10; i++){
			for(int j=0; j<10; j++){
				if(i==j){
					T[i][j] = 0;
				}
				else{
					T[i][j] = INF;
				}
			}
		}

		int m = 0;		// 町の総数

		for(int i=0; i<n; i++){
			int a, b, c;
			cin >> a >> b >> c;

			T[a][b] = T[b][a] = c;

			if(a+1>m){
				m = a+1;
			}
			if(b+1>m){
				m = b+1;
			}
		}

		int d[m][m];
		for(int i=0; i<m; i++){
			for(int j=0; j<m; j++){
				d[i][j]=T[i][j];
			}
		}

		for(int k=0;k<m; k++){
			for(int i=0; i<m; i++){
				for(int j=0; j<m; j++){
					if(d[i][j]>d[i][k]+d[k][j]){
					d[i][j]=d[i][k]+d[k][j];
					}
				}
			}
		}
		int num,min;

		for(int i=0; i<m; i++){
			int a=0;
			for(int j=0; j<m; j++){
				a=a+d[i][j];
			}
			if(min>a){
				min=a;
				num=i;
			}
		}
		cout<<num<<" "<<min<<endl;
  }

	return 0;
}

C++: #include <iostream>
using namespace std;

const int INF = 1000000;
const int town_max = 10;

int main()
{
	while(true){
		int n;
		cin >> n;
		if(n==0)
			break;

		int T[town_max][town_max];
		for(int i=0;i<town_max;i++){
			for(int j=0;j<town_max;j++){
				if(i==j)
					T[i][j] = 0;
				else
					T[i][j] = INF;
			}
		}

		int m = 0;	//頂点の数
		for(int i=0;i<n;i++){
			int a, b, c;	//町の番号は0から
			cin >> a >> b >> c;
			T[a][b] = T[b][a] = c;
			if(a+1>m)
				m = a+1;
			if(b+1>m)
				m = b+1;
		}

		for(int i=0;i<m;i++){
			for(int j=0;j<m;j++){
				for(int k=0;k<m;k++){
					if(T[j][k]>T[j][i]+T[i][k])
						T[j][k] = T[j][i]+T[i][k];
				}
			}
		}


		int T_min = INF;
		int town_min = -1;
		for(int i=0;i<m;i++){
			int T_sum = 0;
			for(int j=0;j<m;j++){
				T_sum += T[i][j];
			}
			if(T_sum<T_min){
				T_min = T_sum;
				town_min = i;
			}
		}

		cout << town_min << " " << T_min << endl;
	}
}

C++: #include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
struct edge{int to;int cost;};
typedef pair<int,int> P;
const int Inf=1e7;
int N;
int A,B,C;
vector<edge>X[10];
int d[10];
int cou;
int main()
{
	while(true){

		int ans1=0,ans2=1e9;
		cou=0;
		scanf("%d",&N);
		if(N==0)break;
		for(int i=0;i<N;i++){
			scanf("%d%d%d",&A,&B,&C);
			edge e1={B,C};
			X[A].push_back(e1);
			edge e2={A,C};
			X[B].push_back(e2);
			cou=max(cou,max(A,B));
		}
		for(int s=0;s<=cou;s++){
			for(int i=0;i<=cou;i++)d[i]=Inf;
			d[s]=0;
			priority_queue<P, vector<P>, greater<P> > que;
			que.push(make_pair(0,s));
			while(!que.empty()){
				P p=que.top();que.pop();
				int v=p.second;
				if(d[v]<p.first)continue;
				for(int i=0;i<X[v].size();i++){
					edge e=X[v][i];
					if(d[e.to]>d[v]+e.cost){
						d[e.to]=d[v]+e.cost;
						que.push(make_pair(d[e.to],e.to));
					}
				}
			}
			//for(int i=0;i<=cou;i++)printf("%d %d %d\n",s,i,d[i]);
			int sum=0;
			for(int i=0;i<=cou;i++)sum+=d[i];
			if(ans2>sum){
				ans2=sum;
				ans1=s;
			}
		}
		printf("%d %d\n",ans1,ans2);
	}
	return 0;
}

C++: #include <cstdio>
#include <vector>
#include <queue>
#include <string>
#include <algorithm>
using namespace std;

const int max_n = 10, INF = 100000000;
struct edge{ int to, cost; };
typedef pair<int, int> P;

int n;
vector<edge> g[max_n];
int d[max_n];
bool exi[max_n];

void dijkstra(int s){
	//priority_que
	priority_queue<P, vector<P>, greater<P> > que;
	fill(d, d + max_n, INF);
	d[s] = 0;
	que.push(P(0, s));//コスト、ノードの順
	
	while(!que.empty()){
		P p = que.top(); que.pop();
		int v = p.second;
		if(d[v] < p.first) continue;//もともと入っていたやつの方が低コスト
		for(int i = 0; i < g[v].size(); i++){
			edge e = g[v][i];
			if(d[e.to] > p.first + e.cost){
				d[e.to] = p.first + e.cost;
				que.push(P(d[e.to], e.to));
			}
		}
	}
}

int main(){
	int res, ans, pos;
	
	while(true){
		scanf("%d", &n);
		if(n == 0) return 0;
		fill(exi, exi + max_n, false);
		for(int i = 0; i < max_n; i++){
			g[i].clear();
		}
		for(int i = 0; i < n; i++){
			int a, b, c;
			scanf("%d%d%d", &a, &b, &c);
			edge p1, p2;
			p1.to = b; p1.cost = c;
			p2.to = a; p2.cost = c;
			g[a].push_back(p1);
			g[b].push_back(p2);
			exi[a] = true; exi[b] = true;
		}
		
		ans = INF;
		pos = 0;
		for(int i = 0; i < 10; i++){
			if(!exi[i]) continue;
			res = 0;
			dijkstra(i);
			for(int j = 0; j < 10; j++){
				if(d[j] != INF){
					res += d[j];
				}
			}
			if(ans > res){
				pos = i;
				ans = res;
			}
		}
		
		printf("%d %d\n", pos, ans);
	}
}