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<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>

using namespace std;

#define INF 100000000

int edges[20][20];
int dist[20][20];

int main(){

    cin.sync_with_stdio(false);

    while(1){

        int N;

        cin >> N;

        if(N == 0) break;

        memset(edges,0,sizeof(edges));

        int ids[20];
        int nids = 0;

        for(int i=0;i<N;++i){

            int x,y,c;

            cin >> x >> y >> c;

            int ix=-1;
            int iy=-1;

            for(int l=0;l<nids;++l){
                if(ids[l]==x) ix = l;
                if(ids[l]==y) iy = l;
            }

            if(ix<0){ ix = nids; ids[nids++]=x; }
            if(iy<0){ iy = nids; ids[nids++]=y; }

            edges[ix][iy] = edges[iy][ix] = c;

        }

        for(int i=0;i<nids;++i){
            for(int j=0;j<nids;++j){
                if(i==j)
                    dist[i][j] = 0;
                else if(edges[i][j]>0)
                    dist[i][j] = edges[i][j];
                else
                    dist[i][j] = INF;
            }
        }

        for(int k=0;k<nids;++k)
            for(int i=0;i<nids;++i)
                for(int j=0;j<nids;++j)
                    dist[i][j] = min(dist[i][j],dist[i][k]+dist[k][j]);

        int ans  = 0;
        int msum = INF;

        for(int i=0;i<nids;++i){

            int sum = 0;
            for(int j=0;j<nids;++j){
               if(dis[i][j]==INF)continue;
               sum += dist[i][j];
            }

            if(sum<=msum){

                if(sum==msum && ids[i]<ids[ans])
                    ans = i;
                else
                    ans = i;

                msum = sum;

            }

        }

        cout << ids[ans] << " " << msum << endl;

    }

    return 0;

}

C++: //
//  main.cpp
//

#include <iostream>
//#include <algorithm>
#include <vector>
//#include <limits>
#include <math.h>
//#include <queue>
//#include <tuple>
//#include <stdio.h>
//#include <stdlib.h>
//#include <string>
//#include "string.h"
// #include <unordered_map>
#include <map>
#include <unordered_set>
//#include <array>
#include <set>
#include <limits>

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2224

using namespace std;

using ll = long long;

#include <vector>

struct UnionFind {
    vector<size_t> parent;
    vector<size_t> rank;
    size_t findParent(size_t x) {
        if (parent[x] == x) {
            return x;
        } else {
            parent[x] = findParent(parent[x]);
            return parent[x];
        }
    }
    explicit UnionFind(size_t size) {
        parent.resize(size);
        rank.resize(size);
        for (size_t i = 0; i < size; i++) {
            parent[i] = i;
            rank[i] = 0;
        }
    }
    virtual ~UnionFind() {}
    void unite(size_t x, size_t y) {
        size_t px = findParent(x);
        size_t py = findParent(y);
        if (px == py) {
            return;
        }
        if (rank[px] < rank[py]) {
            parent[px] = py;
        } else if (rank[px] > rank[py]) {
            parent[py] = px;
        } else { // rank[px] == rank[py]
            parent[py] = px;
            rank[px]++;
        }
    }
    bool isSame(size_t x, size_t y) {
        return findParent(x) == findParent(y);
    }
};

int main() {
    int N, M;
    cin >> N >> M;
    struct Pl {
        int x;
        int y;
        Pl(int x, int y) : x(x), y(y) {}
        double dist(const Pl& rhs) const {
            return sqrt(pow((double)(x - rhs.x), 2.0) + pow((double)(y - rhs.y), 2.0));
        }
    };
    vector<Pl> piles;
    piles.reserve(N);
    for (int i = 0; i < N; i++) {
        int x, y;
        cin >> x >> y;
        piles.emplace_back(x, y);
    }
    struct Fc {
        int a;
        int b;
        double len;
        Fc(int a, int b, double len) : a(a), b(b), len(len) {}
        static bool compareLen(const Fc& lhs, const Fc& rhs) {
            return lhs.len > rhs.len;
        }
    };
    vector<Fc> fences;
    fences.reserve(M);
    double totalLen = 0.0;
    for (int i = 0; i < M; i++) {
        int a, b;
        cin >> a >> b;
        a--;
        b--;
        double len = piles[a].dist(piles[b]);
        fences.emplace_back(a, b, len);
        totalLen += len;
    }
    sort(fences.begin(), fences.end(), Fc::compareLen);
    UnionFind uf(N);
    double lenSum = 0.0;
    for (Fc fc : fences) {
        if (!uf.isSame(fc.a, fc.b)) {
            uf.unite(fc.a, fc.b);
            lenSum += fc.len;
        }
    }
    cout << totalLen - lenSum << endl;
    return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
#include <cctype>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <stdio.h>
#include <string.h>
#include <cstdlib>
#include <math.h>
#include <bitset>
#include <iterator>
#include <iomanip>
#include <sstream>
#include <numeric>
#define INF 2000000000
using namespace std;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
long long gcd(long long a,long long b){if(a%b==0){return b;}else return gcd(b,a%b);}
long long lcm(long long a,long long b){if(a==0){return b;} return a/gcd(a,b)*b;}
long long MOD; template<class T> void mod(T &n){MOD=n;}
#define sym cout<<"---------"<<endl;
#define ll long long
#define PL pair<long long, long long>
#define P pair<int,int>
#define mk make_pair
#define en endl
#define WHITE 1
#define BLACK 2
#define GRAY 1
#define RE return 0
#define int ll


signed main(){
  int n;
  while(cin>>n&&n){
    vector<P> G[15];
    
    int maxl=0;
    for(int i=0; i<n; i++){
      int a,b,c; cin>>a>>b>>c;
      G[a].push_back(mk(b,c));
      G[b].push_back(mk(a,c));
      maxl=max(maxl,max(a,b));
    }
    
    P min_ans; min_ans.first=INF;
    for(int i=0; i<=maxl; i++){
      int c[15];
      bool come[15];
      for(int j=0; j<=10; j++){c[j]=INF; come[j]=false;}
      
      priority_queue<P, vector<P>, greater<P> > que;
      que.push(mk(0,i));
      c[i]=0;
      int sum=0;
      while(!que.empty()){
        int at=que.top().second; int how_much=que.top().first;
        sum+=how_much;
        come[at]=true;
        que.pop();
        for(int j=0; j<G[at].size(); j++){
          int to=G[at][j].first;
          if(come[to]) continue;
          if(c[to]>how_much+G[at][j].second){
            c[to]=how_much+G[at][j].second;
            que.push(mk(c[to],to));
          }
        }
      }
    
      if(min_ans.first>sum){
        min_ans.first=sum; min_ans.second=i;
      }
    }
    
    cout<<min_ans.second<<" "<<min_ans.first<<en;
  }
}