Problem:
Problem 09:
Building Houses
この秋、割火ハウスは最近開拓が進んでいる松短地区の神暗通り沿いの土地を分譲することにした。

先日募集をかけ、今日は購入者に分譲説明会を開催する。
購入者が説明会場に集まりだしたところ、なんだか空気がとても凍り付いていた。不思議に思った担当者は開催前に
「皆さん新天地を求めてきたというのに、ちょっと表情が暗いですが大丈夫ですか？」
と聞いてみた。そこで思わぬ事実が判明した。実は、購入者全員が現在隣町の集合団地の住人で、あまりにも周辺の人たちと折り合いが合わないため今回引越しをしようと検討していたのだった。
購入者たちはすでに費用を支払済みで以前の住まいを引き払っている。従って、今回分譲した松短地区の神暗通りに家を立てる他方法はない。
しかしながら、少しでも快適な新居ライフを送ってもらおうと担当者は頭を悩ませた。よくよく話を聞いてみると、仲の悪さにはバラツキがあったので、聞き込みを行い図１のような仲の悪い度チェック表を作成した：
図１：仲の悪い度チェック表
購入者の数を
n
とすると、表は
n
×
n
の行列となり、要素
a
i,j
は、購入者
i
が自分の家から購入者
j
の家を最低でも何 m 離したいかを示す。例えば、図１の表において、購入者 A は自分の家と購入者 B の家の距離が 2 m 以上離れていないと納得しない。さらに、購入者 B は自分の家と購入者 A の家の距離が 4 m 以上離れていないと納得しない。従って A と B の距離は 4 m 以上離す必要がある。
担当者はこの表に基づき隣の家との間隔を設け土地のレイアウトを設計することにした。
あなたの仕事は、仲の悪い度チェック表を入力し、購入者の家を神暗通り（一直線上）に建てるために最低限必要な通りの長さ（m）を出力するプログラムを作成することである。
なお簡単のために、家は点として扱い、その幅は 0 m と仮定する。
Input
入力として複数のデータセットが与えられる。各データセットは以下の形式で与えられる：
n
（購入者の数：整数）
a
1,1
a
1,2
...
a
1,
n
（
a
1,
j
：整数）
a
2,1
a
2,2
...
a
2,
n
（
a
2,
j
：整数）
.
.
a
n
,1
a
n
,2
...
a
n
,
n
（
a
n
,
j
：整数）
n
は 10　以下とする。
a
i
,
i
は 0 であり、
a
i
,
j
(
i
≠
j
) は 1 以上である。
n
が 0　のとき入力の終わりとする。
Output
各データセットについて、最低限必要な通りの長さを１行に出力せよ。
Sample Input
4
0 2 3 1
4 0 4 2
1 1 0 3
3 1 5 0
2
0 3
3 0
0
Output for the Sample Input
8
3

Submitted solutions:

code_snippet: #include <cstdio>
#include <algorithm>
#include <vector>
#include <climits>
#include <numeric>
using namespace std;

// i を [a,b) の範囲で動かすループマクロ
#define repi(i,a,b) for(int i=int(a); i<int(b); i++)
// i を [0,n) の範囲で動かすループマクロ
#define rep(i,n) repi(i,0,n)
// コンテナ c の begin/end
#define all(c) (c).begin(), (c).end()

int ans;

// 再帰的に perm[0..cur-1] までを配置済みとし、perm[cur..n-1] の順番を試す。
// a[i][j]: i と j の間に必要な最小距離（対称化済み）
// perm: 現在の順列
// pos: perm[k] の家を置いた座標
// cur: これから配置する順列のインデックス
int solve(const vector<vector<int>>& a,
          vector<int>& perm,
          vector<int>& pos,
          int cur)
{
    int n = a.size();
    // ベースケース: 全員配置したら、必要な通りの長さ = max_i pos[i]
    if(cur == n){
        // グローバル ans を更新
        ans = min(ans, *max_element(all(pos)));
        return ans;
    }
    int res = INT_MAX;
    // すでに配置済みの右端を求める
    int right = 0;
    rep(t, cur){
        right = max(right, pos[ perm[t] ]);
    }
    // cur 以降の要素を cur に持ってきて試す
    repi(i, cur, n){
        swap(perm[cur], perm[i]);
        int id = perm[cur];
        // この家を置く最小座標を求める
        int best = right;
        rep(j, cur){
            int prev = perm[j];
            // prev と id の距離制約を満たすには
            best = max(best, pos[prev] + a[id][prev]);
        }
        // これ以上 ans を超えるなら枝刈り
        if(best < ans){
            pos[id] = best;
            res = min(res, solve(a, perm, pos, cur+1));
        }
        swap(perm[cur], perm[i]);
    }
    return res;
}

int main(){
    while(true){
        int n;
        if(scanf("%d",&n)!=1 || n==0) break;
        // 入力行列 a[i][j]
        vector<vector<int>> a(n, vector<int>(n));
        rep(i,n) rep(j,n){
            scanf("%d",&a[i][j]);
        }
        // 対称化：両者の希望距離の大きい方を採用
        rep(i,n) rep(j,n){
            a[i][j] = max(a[i][j], a[j][i]);
        }
        // 初期の順列と配置座標
        vector<int> perm(n), pos(n,0);
        iota(all(perm), 0);
        // ans を大きな値で初期化
        ans = INT_MAX;
        // 再帰探索スタート
        int answer = solve(a, perm, pos, 0);
        printf("%d\n", answer);
    }
    return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 2728
final_rank: 11

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    while (cin >> n, n) {
        vector<vector<ll>> a(n, vector<ll>(n));
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cin >> a[i][j];
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                a[i][j] = max(a[i][j], a[j][i]);
            }
        }
        ll res = 1e18;
        vector<bool> done(n);
        vector<int> v(n);
        vector<ll> d(n);
        auto dfs = [&](auto dfs, int i) -> void {
            if (i == n) {
                res = min(res, d.back());
                return;
            }
            // cout << i << endl;
            for (int j = 0; j < n; j++) {
                if (done[j]) continue;
                ll mx = 0;
                for (int k = 0; k < i; k++) {
                    mx = max(mx, d[k] + a[v[k]][j]);
                }
                if (mx >= res) break;
                done[j] = true;
                d[i] = mx;
                v[i] = j;
                dfs(dfs, i + 1);
                done[j] = false;
            }
        };
        dfs(dfs, 0);
        cout << res << "\n";
    }
}
accuracy: 1
time_ms: 140
memory_kb: 3376
final_rank: 13

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


int N;
int ans;
bool used[10];
int table[10][10],position[10];

void recursive(int loc,int count){

	if(count == N){
		ans = min(ans,loc);
		return;
	}

	int next_loc;

	for(int i = 0; i < N; i++){
		if(used[i])continue;

		//既に配置済の人物から、次の配置場所を特定する

		next_loc = loc;
		for(int k = 0; k < N; k++){
			if(!used[k])continue;
			if(loc-position[k] >= table[i][k])continue; //必要以上離れていればSKIP

			next_loc = max(next_loc,position[k]+table[i][k]);
		}

		if(next_loc >= ans)continue; //次の場所がans以上ならskip

		used[i] = true;
		position[i] = next_loc;
		recursive(next_loc,count+1);
		used[i] = false;
		position[i] = -1;
	}
}

void func(){

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++)scanf("%d",&table[row][col]);
	}

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			table[row][col] = max(table[row][col],table[col][row]);
		}
	}

	for(int i = 0; i < N; i++){
		used[i] = false;
		position[i] = -1;
	}

	ans = BIG_NUM;

	for(int first = 0; first < N; first++){
		position[first] = 0;
		used[first] = true;
		recursive(0,1);
		position[first] = -1;
		used[first] = false;
	}

	printf("%d\n",ans);
}

int main(){

	while(true){
		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 770
memory_kb: 3092
final_rank: 19

code_snippet: #include <bits/stdc++.h>

using namespace std;

const int INF = 1 << 30;

int main()
{
  int N, A[10][10];
  while(cin >> N, N) {
    for(int i = 0; i < N; i++) {
      for(int j = 0; j < N; j++) {
        cin >> A[i][j];
      }
    }
    for(int i = 0; i < N; i++) {
      for(int j = 0; j < N; j++) {
        A[i][j] = max(A[i][j], A[j][i]);
      }
    }

    int ret = INF;
    vector< int > s(N), p(N, 0);
    iota(begin(s), end(s), 0);
    int loop = 0;
    do {
      if(loop++ >= 3000000) break;
      int i = 1;
      while(i < s.size()) {
        p[i] = 0;
        for(int j = i - 1; j >= 0; j--) {
          p[i] = max(p[i], A[s[j]][s[i]] + p[j]);
        }
        if(p[i++] >= ret) break;
      }
      ret = min(ret, p.back());
    } while(next_permutation(begin(s), end(s)));

    cout << ret << endl;
  }
}
accuracy: 1
time_ms: 970
memory_kb: 3056
final_rank: 20

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define INF (1<<29)

int a[10][10], res;

void dfs(int n, int S, int cost,
        vector<int> &p, vector<int> &pos)
{
    if (S == (1<<n)-1) {
        res = min(res, cost);
        return;        
    }

    if (res <= cost) return;
    
    for (int i = 0; i < n; i++) {
        if (S >> i & 1) continue;
        int npos = 0;
        for (int j = 0; j < (int)pos.size(); j++) {
            npos = max(npos, pos[j] + a[p[j]][i]);
        }
        p.push_back(i);
        pos.push_back(npos);

        dfs(n, S|(1<<i), npos, p, pos);
        
        p.pop_back();
        pos.pop_back();
    }

}

int main()
{
    int n;
    while (cin >> n, n) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cin >> a[i][j];
            }
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                a[i][j] = max(a[i][j], a[j][i]);
            }
        }
        
        res = INF;
        vector<int> p, pos;        
        dfs(n, 0, 0, p, pos);
        cout << res << endl;
    }    
    return 0;
}
accuracy: 1
time_ms: 410
memory_kb: 3092
final_rank: 17

code_snippet: #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int n;
int d[10][10];

bool bound(int k, long long *length, bool used[], int home[], long long c[], const int n)
{
  bool res = false;
  long long lb;                 // ??????????????¢?´¢?????????
  int t = home[k-1];
  lb = c[k-1];

  int m = 0;
  for (int i=0;i<n;i++)
  {
    if (!used[i])
    {
      m = max(m, d[t][i]);
    }
  }
  // ????????????????????§??????????§£??????????????´???
  if (lb + max(m, n-k+1) >= *length && *length > 0) res = true;
  return res;
}

void dfs(int k, long long *length, bool used[], int home[], long long c[], const int n)
{
  if (k == n)
  {
    if (*length > c[n-1] || *length == 0) *length = c[n-1];
    return;
  }
  else if (k > 0 && *length > 0 && bound(k, length, used, home, c, n)) return;
  else
  {
    for (int i=0;i<n;i++)
    {
      if (!used[i])
      {
        used[i] = true;
        home[k] = i;
        if (k == 0) c[k] = 0;
        else
        {
          c[k] = c[k-1] + d[home[k]][home[k-1]];
          for (int j=k-2;j>=0;j--) c[k] = max(c[k], c[j] + d[home[k]][home[j]]);
        }
        dfs(k+1, length, used, home, c, n);
        used[i] = false;
      }
    }
  }
  return ;
}

int main()
{
  while (1)
  {
    cin >> n;
    if (n == 0) return 0;

    for (int i=0;i<n;i++) for (int j=0;j<n;j++) cin >> d[i][j];
    for (int i=0;i<n;i++) for (int j=0;j<n;j++) d[i][j] = max(d[i][j], d[j][i]);

    long long length = 0;
    bool used[10] = {false, false, false, false, false, false, false, false, false, false};
    int home[10];
    long long c[10];

    dfs(0, &length, used, home, c, n);
    cout << length << endl;
  }
}
accuracy: 1
time_ms: 200
memory_kb: 1156
final_rank: 1

code_snippet: #include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

int n;
int d[10][10];

bool bound(int k, long long *length, bool used[], int home[], long long c[], const int n)
{
  bool res = false;
  long long lb;                 // ??????????????¢?´¢?????????
  int t = home[k-1];
  lb = c[k-1];

  int m = 0, mm = 99999;
  for (int i=0;i<n;i++)
  {
    if (!used[i])
    {
      m = max(m, d[t][i]);
      //mm = min(mm, d[t][i]);
    }
  }
  if (lb + max(m, n-k+1) >= *length && *length > 0) res = true; // ????????????????????§??????????§£??????????????´???
  return res;
}

void dfs(int k, long long *length, bool used[], int home[], long long c[], const int n)
{
  if (k == n)
  {
    //for (int i=0;i<n;i++) cout << home[i]; cout << ' ' << c[n-1] << endl;
    if (*length > c[n-1] || *length == 0) *length = c[n-1];
    return;
  }
  else if (k > 0 && *length > 0 && bound(k, length, used, home, c, n)) return;
  else
  {
    for (int i=0;i<n;i++)
    {
      if (!used[i])
      {
        used[i] = true;
        home[k] = i;
        if (k == 0) c[k] = 0;
        else
        {
          c[k] = c[k-1] + d[home[k]][home[k-1]];
          for (int j=k-2;j>=0;j--) c[k] = max(c[k], c[j] + d[home[k]][home[j]]);
        }
        dfs(k+1, length, used, home, c, n);
        used[i] = false;
      }
    }
  }
  return ;
}

int main()
{
  while (1)
  {
    cin >> n;
    if (n == 0) return 0;

    for (int i=0;i<n;i++) for (int j=0;j<n;j++) cin >> d[i][j];
    for (int i=0;i<n;i++) for (int j=0;j<n;j++) d[i][j] = max(d[i][j], d[j][i]);

    long long length = 0;
    bool used[10] = {false, false, false, false, false, false, false, false, false, false};
    int home[10];
    long long c[10];

    dfs(0, &length, used, home, c, n);
    cout << length << endl;
  }
}
accuracy: 1
time_ms: 210
memory_kb: 1156
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;

int n,ans;
int a[10][10], use[10], perm[10], pos[10];

void dfs(int d, int r){
  if(d==n){
    ans = r; return;
  }

  for(int i=0;i<n;i++){
    if(!use[i]){
      use[i] = 1;

      perm[d] = i; pos[d] = 0;
      for(int j=0;j<d;j++){
	pos[d] = max(pos[d], pos[j] + a[i][perm[j]]);
      }
      if(pos[d]<ans)dfs(d+1,pos[d]);

      use[i] = 0;
    }
  } 
}

int main(){
  while(cin >> n,n){
    for(int i=0;i<n;i++)for(int j=0;j<n;j++){
	cin >> a[i][j];
	if(j<i)a[i][j] = a[j][i] = max(a[i][j],a[j][i]);
      }

    memset(use,0,sizeof(use));
    ans = 1e9;
    dfs(0,0);
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 360
memory_kb: 1160
final_rank: 6

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
int perm[11];
int g[11][11];
int d[11];
int v[11];
int ret;
int n;
void solve(int a){
	if(a==n){ret=d[n-1];return;}
	for(int i=0;i<n;i++){
		if(v[i])continue;
		int at=0;
		for(int j=0;j<a;j++)at=max(at,d[j]+g[i][perm[j]]);
		if(at<ret){
			v[i]=1;
			perm[a]=i;
			d[a]=at;
			solve(a+1);
			v[i]=0;
		}
	}
}
int main(){
	int a;
	while(scanf("%d",&a),a){
		n=a;
		for(int i=0;i<a;i++){
			for(int j=0;j<a;j++){
				scanf("%d",&g[i][j]);
			}
		}
		for(int i=0;i<a;i++)for(int j=i+1;j<a;j++){
			g[i][j]=g[j][i]=max(g[i][j],g[j][i]);
		}
		for(int i=0;i<a;i++)perm[i]=i;
		ret=999999999;
		for(int i=0;i<a;i++)v[i]=0;
		solve(0);
		printf("%d\n",ret);
	}
}
accuracy: 1
time_ms: 350
memory_kb: 1012
final_rank: 5

code_snippet: #include<iostream>
#include<vector>
#include<utility>
#include<algorithm>

using namespace std;

int n;
int a[10][10];

int dfs(const vector<pair<int,int> > &v,int b,int m){
  if(b+1==1<<n)return v.back().second;
  for(int i=0;i<n;i++){
    if(!(b>>i&1)){
      int p=0;
      for(auto e:v){
	p=max(p,e.second+a[e.first][i]);
      }
      if(m<=p)continue;
      auto nv=v;
      nv.emplace_back(i,p);
      m=min(m,dfs(nv,b|1<<i,m));
    }
  }
  return m;
}

int main(){
  while(cin>>n,n){
    for(int i=0;i<n;i++){
      for(int j=0;j<n;j++){
	cin>>a[i][j];
      }
    }
    for(int i=0;i<n;i++){
      for(int j=0;j<i;j++){
	a[i][j]=a[j][i]=max(a[i][j],a[j][i]);
      }
    }
    cout<<dfs(vector<pair<int,int> >(),0,1<<29)<<endl;
  }
}
accuracy: 1
time_ms: 750
memory_kb: 1200
final_rank: 14

code_snippet: #include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;

template<class T> inline void chmax(T &a, const T &b) { if(a < b) a = b; }

constexpr int MAX_N = 10;
constexpr int INF = (1 << 29);

int n;
int a[MAX_N][MAX_N];

int ans;
int dist[MAX_N];

void dfs(int index) {
	for(int i = 0; i < n; ++i) {
		if(dist[i] != INF) continue;

		int max_dist = 0;
		for(int j = 0; j < n; ++j) {
			if(dist[j] != INF) {
				chmax(max_dist, dist[j] + a[i][j]);
			}
		}

		if(max_dist >= ans) continue;
		if(index == n - 1) {
			ans = max_dist;
			return;
		}

		dist[i] = max_dist;
		dfs(index + 1);
		dist[i] = INF;
	}
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	fill(dist, dist + MAX_N, INF);
	while(cin >> n && n) {
		for(int i = 0; i < n; ++i) {
			for(int j = 0; j < n; ++j) {
				cin >> a[i][j];
			}
		}

		for(int i = 0; i < n; ++i) {
			for(int j = 0; j < n; ++j) {
				a[i][j] = a[j][i] = max(a[i][j], a[j][i]);
			}
		}

		ans = INF;
		dfs(0);
		cout << ans << endl;
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 640
memory_kb: 1196
final_rank: 12

code_snippet: #include <iostream>
#include <sstream>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cassert>

using namespace std;

#define FOR(i,k,n) for(int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
#define FORIT(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();++i)

template<class T> void debug(T begin, T end){ for(T i = begin; i != end; ++i) cerr<<*i<<" "; }
inline bool valid(int x, int y, int W, int H){ return (x >= 0 && y >= 0 && x < W && y < H); }

typedef long long ll;
const int INF = 100000000;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
bool used[10];
int parm[10];
int N;
int a[10][10];
int dist[10];
int ans;
void dfs(int idx){
  if(idx == N){
    ans = dist[idx - 1];
    return;
  }
  for(int i = 0; i < N; i++) if(!used[i]){
    parm[idx] = i;
    used[i] = true;
    dist[idx] = 0;
    for(int j = 0; j < idx; j++){
      dist[idx] = max(dist[idx], dist[j] + a[parm[j]][parm[idx]]);
    }
    if(dist[idx] < ans) dfs(idx + 1);
    used[i] = false;
  }
}

int main(){
  while(cin >> N && N){
    REP(i, N){
      REP(j, N){
        cin >> a[i][j];
      }
    }
    REP(i, N)REP(j, N) a[i][j] = max(a[i][j], a[j][i]);
    memset(used, 0, sizeof(used));
    ans = INF;
    dfs(0);
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 390
memory_kb: 1160
final_rank: 8

code_snippet: #include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

#define repi(i,a,b) for(int i=int(a);i<int(b);i++)
#define rep(i,n) repi(i,0,n)
#define all(c) begin(c),end(c)

typedef vector<int> vi;
typedef vector<vi> vvi;

int ans;

int solve(const vvi& a,vi& perm,vi& pos,int cur)
{
	int n=a.size();
	if(cur==a.size())
		return ans=min(ans,*max_element(all(pos)));
	
	int res=1<<29,right=0;
	rep(i,cur)
		right=max(right,pos[perm[i]]);
	repi(i,cur,n){
		swap(perm[cur],perm[i]);
		int mx=0;
		rep(j,cur){
			int x=perm[cur],y=perm[j];
			mx=max(mx,pos[y]+a[x][y]);
		}
		if(mx<ans){
			pos[perm[cur]]=mx;
			res=min(res,solve(a,perm,pos,cur+1));
		}
		swap(perm[cur],perm[i]);
	}
	return res;
}

int main()
{
	for(int n;scanf("%d",&n),n;){
		vvi a(n,vi(n));
		rep(i,n) rep(j,n)
			scanf("%d",&a[i][j]);
		rep(i,n) rep(j,n)
			a[i][j]=max(a[i][j],a[j][i]);
		
		vi perm(n),pos(n); iota(all(perm),0);
		ans=1<<29;
		printf("%d\n",solve(a,perm,pos,0));
	}
	
	return 0;
}
accuracy: 1
time_ms: 280
memory_kb: 1052
final_rank: 3

code_snippet: #include<stdio.h>
#include<string.h>
#include<algorithm>
int ans,lens[11],data[11][11];
bool spents[11];

int n;

void saiki(int deep,int l){
	if(deep==n){
		if(ans==-1)ans=l;
		ans=std::min(ans,l);
	}else{
		int back[11];
		bool out=false;
		memcpy(back,lens,sizeof(lens));
		for(int i=0;i<n;i++){
			if(spents[i]==false){
				spents[i]=true;
				int len=lens[i];
				for(int j=0;j<n;j++){
					if(spents[j]==false)lens[j]=std::max(len+data[i][j],lens[j]);
					if(ans>-1&&ans<=lens[j]&&spents[j]==false)out=true;
				}
				if(out==false)saiki(deep+1,len);
				out=false;
				memcpy(lens,back,sizeof(back));
				spents[i]=false;
			}
		}
	}
}

void setData(){
	
	ans=-1;
	memset(data,0,sizeof(data));
	for(int i=0;i<n;i++){
		spents[i]=false;
		lens[i]=0;
		for(int j=0;j<n;j++){
			scanf("%d",&data[i][j]);
			data[i][j]=data[j][i]=std::max(data[i][j],data[j][i]);
		}
	}
	saiki(0,0);
	printf("%d\n",ans);
}

int main(){
	while(1){
		scanf("%d",&n);
		if(n==0)break;
		setData();
	}
}
accuracy: 1
time_ms: 370
memory_kb: 764
final_rank: 4

code_snippet: #include <vector>
#include <algorithm>
#include <iostream>
#include <cstring>

using namespace std;

int n;
int g[10][10];
int dist[10] = {};
int maxHate[10] = {};
int minHate[10] = {};
int ord[10];
int maxRest[10][1<<10];

int solve(){
	if (n == 1) return 0;
	ord[1] = 0;
	int minD = 1 << 30;
	int sumMinHate = 0;
	for (int i = 0; i < n; ++i) sumMinHate += minHate[i];
	do{
		int pOne = -1;
		int used = (1 << ord[0]);
		int rest = sumMinHate - minHate[ord[0]];
		bool one = ord[0] == 0;
		for (int i = 1; i < n; ++i) {
			int p = ord[i];
			if (ord[i] == 0) {
				if (one) {
					pOne = i;
					p = ord[i] = 1;
				}
				one = !one;
			}
			rest -= minHate[p];
			dist[i] = dist[i-1];
			for (int j = i-1; j >= 0; --j) {
				if (dist[i] - dist[j] >= maxRest[p][used]) break;
				dist[i] = max(dist[i], dist[j] + g[p][ord[j]]);
			}
			if (dist[i] + rest >= minD) {
				dist[n-1] = 1 << 30;
				break;
			}
			used += 1 << p;
		}
		minD = min(minD, dist[n-1]);
		if (pOne != -1) ord[pOne] = 0;
	} while (next_permutation(ord, ord+n));
	return minD;
}

int main(){
	int trailZero[1024] = {};
	for (int i = 0; i < 10; ++i) {
		trailZero[(1 << (i+1)) - 1] = i;
	}
	while(true) {
		cin >> n;
		if (n == 0 || cin.eof()) break;
		for (int i = 0; i < n; ++i) {
			ord[i] = i;
			minHate[i] = 1 << 30;
			maxHate[i] = 0;
			for (int j = 0; j < n; ++j) {
				scanf("%d", g[i] + j);
			}
		}
		memset(maxRest, 0, sizeof(maxRest));
		for (int i = 0; i < n; ++i) {
			for (int j = i+1; j < n; ++j) {
				g[i][j] = g[j][i] = max(g[i][j], g[j][i]);
				maxHate[i] = max(maxHate[i], g[i][j]);
				maxHate[j] = max(maxHate[j], g[i][j]);
				minHate[i] = min(minHate[i], g[i][j]);
				minHate[j] = min(minHate[j], g[i][j]);
			}
		}
		for (int j = 1; j < (1 << n); ++j) {
			for (int k = 0; k < n; ++k) {
				if ((j & (1 << k)) == 0 || j == (1 << k)) continue;
				int st = j - (1 << k);
				int prev = st & (st-1);
				int pos = trailZero[st ^ (st-1)];
				maxRest[k][st] = max(maxRest[k][prev], g[k][pos]);
			}
		}
		printf("%d\n", solve());
	}
}
accuracy: 1
time_ms: 940
memory_kb: 960
final_rank: 18

code_snippet: #include<cstdio>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const int INF=1<<29;

int n,d[10][10];

int pos[10],ans;
bool used[10];
void dfs(int right){
	if(right>=ans) return;

	int na=0,a[10],nb=0,b[10];
	rep(i,n){
		if(!used[i]) a[na++]=i;
		else         b[nb++]=i;
	}

	if(na==0){ ans=right; return; }

	int lb=right;
	rep(i,na) rep(j,nb) {
		int u=a[i],v=b[j];
		lb=max(lb,pos[v]+d[v][u]);
	}
	if(lb>=ans) return;

	rep(i,na){
		int u=a[i],v;
		rep(j,nb) v=b[j], pos[u]=max(pos[u],pos[v]+d[v][u]);
		used[u]=true;

		dfs(pos[u]);

		pos[u]=0;
		used[u]=false;
	}
}

int main(){
	for(;scanf("%d",&n),n;){
		rep(i,n) rep(j,n) scanf("%d",d[i]+j);
		rep(i,n) rep(j,n) d[i][j]=max(d[i][j],d[j][i]);

		ans=INF;
		dfs(0);

		printf("%d\n",ans);
	}
	return 0;
}
accuracy: 1
time_ms: 640
memory_kb: 764
final_rank: 10

code_snippet: #include<iostream>
#include<climits>
#include<cstdio>
#include<algorithm>
#include<cstring>

using namespace std;

#define REP(i,n) for(int i=0; i<(int)(n); i++)

int g[10][10];
int n;
int ans;
int m[10];
int flag[10];
int p[10];

void solve(int pos, int nn){
  int now = p[nn - 1];
  if(nn == n){
    ans = min(ans, now);
  }else if(now < ans){
    REP(i,n) if(!flag[i]){
      int dst = 0;
      flag[i] = 1;
      m[nn] = i;
      REP(j, nn) dst = max(dst, p[j] + g[i][m[j]]);
      p[nn] = dst;
      solve(i, nn + 1);
      flag[i] = 0;
    }
  }
}

int main(){
  while(scanf("%d", &n), n){
    REP(i,n) REP(j,n)
      scanf("%d", &g[i][j]);
    REP(i,n) REP(j,n)
      g[i][j] = max(g[i][j], g[j][i]);

    ans = INT_MAX;

    REP(i,n){
      m[0] = i;
      flag[i] = 1;
      solve(i, 1);
      flag[i] = 0;
    }
    printf("%d\n", ans);
  }
  return 0;
}
accuracy: 1
time_ms: 690
memory_kb: 0
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int p[10];
int field[10][10];
int a[10];

int main(){
    const int INF=1000000000;
    int n;
    while(scanf("%d",&n),n!=0){
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                scanf("%d",&field[i][j]);
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                field[i][j]=max(field[i][j],field[j][i]);
        for(int i = 0; i < 10; i++)
            a[i]=i;
        int minLength=INF;
        do{
            // »ÝÌÔÅÅáÀKvÈ·³
            int least=0;
            for(int i = 1; i < n; i++)
                least+=field[a[i]][a[i-1]];
            if(least>=minLength)
                continue;
            // aÌÔÉ¨¢Ä¢­
            for(int i = 0; i < n; i++){
                int rightPlace=0;
                if(i==0)
                    rightPlace=0;
                else{
                    // ±±ðÇ¤üP·é©H
                    for(int j = 0; j < i; j++)
                        rightPlace=max(rightPlace,field[a[i]][a[j]]+p[j]);
                }
                p[i]=rightPlace;
                if(p[i]>=minLength)
                    break;
            }
            if(minLength>p[n-1])
                minLength=p[n-1];
        }while(next_permutation(a,a+n));
        printf("%d\n",minLength);
    }
    return 0;
}
accuracy: 1
time_ms: 830
memory_kb: 876
final_rank: 15

code_snippet: #include <cstdio>
#include <iostream>
#include <queue>
#include <set>
using namespace std;

int n;

struct NODE{
	int v[10],o[10];
	int depth;
	NODE(){};
};
int sz;
int dist[10][10];
NODE q;
int ans;
void f(int cur){
	if(cur >= ans) return;
	if(sz == n){
		ans = cur;
		return;
	}
	for(int i = 0 ; i < n ; i++){
		if(q.o[i] == -1){
			int mx = 0;
			for(int j = 0 ; j < sz ; j++){
				mx = max(q.o[q.v[j]]+dist[q.v[j]][i],mx);
			}
			q.v[sz] = i;
			q.o[i] = mx;
			int t = q.depth;
			q.depth = mx;
			sz++;
			f(mx);
			sz--;
			q.depth = t;
			q.o[i] = -1;
		}
	}
}
int main(){
	while(cin >> n && n){
		for(int i = 0 ; i < n ; i++)
			for(int j = 0 ; j < n ; j++)
				dist[i][j] = -1;
		for(int i = 0 ; i < n ; i++){
			for(int j = 0 ; j < n ; j++){
				scanf("%d",&dist[i][j]);
				dist[i][j] = dist[j][i] = max(dist[i][j],dist[j][i]);
			}
		}
		ans = (1<<30);
		sz = 0;
		for(int i = 0 ; i < 10 ; i++) q.o[i] = -1;
		f(0); 
		
		cout << ans << endl;
	}
}
accuracy: 1
time_ms: 660
memory_kb: 0
final_rank: 7

code_snippet: #include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

vector<bool> check;

void dfs(vector<vector<int> >& a, vector<int> pos, int& ret)
{
    int n = a.size();

    if(count(pos.begin(), pos.end(), -1) == n - 1){
        ret = min(ret, *(max_element(pos.begin(), pos.end())));
        return;
    }

    for(int i=0; i<n; ++i){
        if(pos[i] == -1)
            continue;

        vector<int> pos2 = pos;
        int maxPos = 0;
        for(int j=0; j<n; ++j){
            if(pos2[j] != -1){
                pos2[j] = max(pos2[j], pos2[i] + a[i][j]);
                maxPos = max(maxPos, pos2[j]);
            }
        }
        pos2[i] = -1;

        if(maxPos >= ret)
            continue;
        dfs(a, pos2, ret);
    }
}

int solve(vector<vector<int> >& a)
{
    int n = a.size();
    vector<int> pos(n, 0);
    int ret = INT_MAX;
    dfs(a, pos, ret);
    return ret;
}

int main()
{
    for(;;){
        int n;
        cin >> n;
        if(n == 0)
            return 0;

        vector<vector<int> > a(n, vector<int>(n, 0));
        for(int i=0; i<n; ++i){
            for(int j=0; j<n; ++j){
                int tmp;
                cin >> tmp;
                a[i][j] = a[j][i] = max(a[i][j], max(a[j][i], tmp));
            }
        }
        cout << solve(a) << endl;
    }
}
accuracy: 1
time_ms: 920
memory_kb: 908
final_rank: 16