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 <cstring>
#include <queue>
#include <map>
#include <functional>
using namespace std;
//int INF = 1 << 24;

int mins(int p,int q){
  if(p<0)return q;
  else if(q<0 || p<q)return p;
  else return q;
}
int n,i,j;
int a,b,c;
int ari,man;
int lo,no,tai,mi;
typedef pair<int,int> mp;
mp pa;
int mati[10][11][2];
int daiyo[11][2];
//mati[i][0][0]に辺の数
//daiyo[i][0]は確認フラグ
//mati[i][n][0]に先の街
//mati[i][n][1]に距離
//daiyo[i][1]は距離
int main(void){
  scanf("%d",&n);
  while(n!=0){
    memset(mati,0,sizeof(mati));
    man=0;
    for(i=0;i<n;i++){
      scanf("%d%d%d",&a,&b,&c);
      mati[a][0][0]++;
      mati[a][mati[a][0][0]][0]=b;
      mati[a][mati[a][0][0]][1]=c;
      mati[b][0][0]++;
      mati[b][mati[b][0][0]][0]=a;
      mati[b][mati[b][0][0]][1]=c;
      man=(man<a)?a:man;
      man=(man<b)?b:man;
    }
    //mati[i][0][0]に辺の数
    //daiyo[i][0]は確認フラグ
    //mati[i][n][0]に先の街
    //mati[i][n][1]に距離
    //daiyo[i][1]は距離
    int ans=-1;
    int saima=-1;
    for(i=0;i<=man;i++){
      memset(daiyo,-1,sizeof(daiyo));
      priority_queue<mp,vector<mp>,greater<mp> > que;
      que.push(make_pair(0,i));
      daiyo[i][1]=0;
      while(!(que.empty())){
	pa=que.top();
	que.pop();
	no=pa.second;
	if(daiyo[no][0]==-1){
	  lo=pa.first;
	  for(j=1;j<=mati[no][0][0];j++){
	    tai=mati[no][j][0];
	    mi=mati[no][j][1];
	    daiyo[tai][1]=mins(daiyo[tai][1],lo+mi);
	    //printf("%d%d",daiyo[tai][1],lo+mi);
	    que.push(make_pair(daiyo[tai][1],tai));
	  }
	  daiyo[no][0]=1;
	}
      }
      int taans=0;
      for(j=0;j<=man;j++){
	taans+=daiyo[j][1];
      }
      if(ans==-1 || taans<ans){
	ans=taans;
	saima=i;
      }
      //printf("%d %d %d\n",daiyo[0][1],daiyo[1][1],taans);
    }
    printf("%d %d\n",saima,ans);
    scanf("%d",&n);
  }
  return 0;
}

C++: #include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int INF = 0x3f3f3f3f;


int n;
int ans,res,no;
int d[11][11];
int V;

int main()
{
	while(cin>>n)
	{
		if(n==0)
		{
			return 0;
		}
		memset(d,INF,sizeof(d));
		for(int i = 0;i < 11;i++)
		{
			d[i][i] = 0;
		}
		V = 0;ans = INF;
		for(int i = 1;i <= n;i++)
		{
			int a,b,c;
			cin>>a>>b>>c;
			d[a][b] = c;
			d[b][a] = c;
			V = max(V,max(a,b) + 1);   
		}
		for(int k = 0;k < V;k++)
		{
			for(int i = 0;i < V;i++)
			{
				for(int j = 0;j < V;j++)
				{
					d[i][j] = min(d[i][j],d[i][k] + d[k][j]);
				}
			}
		}
		for(int i = 0;i < V;i++)
		{
			res = 0;
			for(int j = 0;j < V;j++)
			{
				res = res + d[i][j];
			}
			if(res < ans)
			{
				ans = res;
				no = i;
			}
		}
		cout<<no<<" "<<ans<<endl;
	}
}

C++: #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;
			}
		}
		
		for(int k=0;k<m;k++){
			for(int i=0;i<m;i++){
				for(int j=0;j<m;j++){
					if(T[i][j]>T[i][k]+T[k][j]){
						T[i][j]=T[i][k]+T[k][j];
					}
				}
			}
		}
		int count1[m];
		for(int k=0;k<m;k++){
			int count=0;
			for(int i=0;i<m;i++){
				count=T[k][i]+count;
			}
			count1[k]=count;
		}
		int count2=count1[0];
		for(int k=0;k<m;k++){
			if(count1[k]<count2)
				count2=count1[k];
		}
		for(int k=0;k<m;k++){
			if(count1[k]==count2)
				cout<<k<<" "<<count2<<endl;
		}

	}

	return 0;
}

C++: #include "bits/stdc++.h"

#define REP(i,num) for(int i=0;i<(num);++i)
#define LOOP(i) while(i--)
#define ALL(c) c.begin(),c.end()
#define PRINTALL(c) for(auto pitr=c.begin();pitr!=c.end();++pitr){cout<<*pitr;if(next(pitr,1)!=c.end())cout<<' ';}cout<<endl;
#define PAIRCOMP(c,comp) [](const pair<ll,ll>& lhs,const pair<ll,ll>& rhs){return lhs.c comp rhs.c;}

using namespace std;
using ll = long long;

constexpr ll atcoder_mod = 1e9+7;

template<typename T=int>
T in(){T x; cin >> x; return (x);}
template<typename T=int,typename C=vector<T>>
C vecin(int N){C x(N);REP(i,N){x[i]=in<T>();}return move(x);}

void vout(){cout << endl;}
template<typename Head,typename... Tail>
void vout(Head&& h,Tail&&... t){cout << ' ' << h;vout(forward<Tail>(t)...);}
void out(){cout << endl;}
template<typename Head,typename... Tail>
void out(Head&& h,Tail&&... t){cout << h;vout(forward<Tail>(t)...);}

class ConnectNodeInfo{
	vector<vector<pair<ll,ll>>> graph;
public:
	ConnectNodeInfo(int node_num){
		graph.resize(node_num);
	}
	void AddNonDirectionalConnection(ll u,ll v,ll w){
		graph[u].emplace_back(v,w);
		graph[v].emplace_back(u,w);
	}
	void AddDirectionalConnection(ll u,ll v,ll w){
		graph[u].emplace_back(v,w);
	}
	vector<pair<ll,ll>>& operator[](ll index){
		return graph[index];
	}
	size_t size(){return graph.size();}
};

class WarshallFloyd{
	vector<vector<ll>> dist;
public:
	void CalcShortestPath(ConnectNodeInfo& connect){
		int V = connect.size();
		dist.resize(V,vector<ll>(V,1LL<<60));

		REP(i,V){
			dist[i][i]=0;
			int U = connect[i].size();
			REP(j,U){
				dist[i][connect[i][j].first] = connect[i][j].second;
			}
		}

		REP(k,V){
			REP(i,V){
				REP(j,V){
					if(dist[i][k]!=(1LL<<60) && dist[k][j]!=(1LL<<60)){
						dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
					}
				}
			}
		}
	}
	bool HasNegativeLoop(){
		bool flag = false;
		for(int i=0,ei=dist.size();i<ei;i++){
			if(dist[i][i]<0){
				flag = true;
				break;
			}
		}
		return flag;
	}
	ll CalcDiameter(){
		ll diameter = -(1LL<<60);
		int V = dist.size();
		REP(i,V){
			REP(j,V){
				if(dist[i][j]<1LL<<60){
					diameter = max(diameter,dist[i][j]);
				}
			}
		}
		return diameter;
	}
	ll GetDistance(int i,int j){
		return dist[i][j];
	}
};

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout<<fixed<<setprecision(10);

	while(true){
		int N=in();
		if(!N) break;
		
		ConnectNodeInfo connect(10);
		REP(i,N){
			int u=in(),v=in(),w=in();
			connect.AddNonDirectionalConnection(u,v,w);
		}

		WarshallFloyd WF;
		WF.CalcShortestPath(connect);
		ll ansI,ansD=1LL<<60;
		REP(i,10){
			if(connect[i].empty()) continue;
			ll sum = 0;
			REP(j,10){
				auto dist = WF.GetDistance(i,j);
				if(dist<1LL<<60) sum+=dist;
			}
			if(sum<ansD){
				ansI = i;
				ansD = sum;
			}
		}
		out(ansI,ansD);
	}
	return 0;
}