Problem:
問題文
$1,2,...,N$ を並べ替えた順列がある。2つの異なる数字 $i$, $j$ を選んで入れ替えることを繰り返してソートされた状態( $1,2,...,N$ の順番に並んだ状態)にしたい。
数字 $i$, $j$ を入れ替える度にコストが $c_{i,j}$ 必要になる。
順列 $p$ に対して、 $p$ をソートするのに必要な最小コストを $f(p)$ とする。
$f(p)$ のとりうる最大値を求めよ。
入力
入力は以下のフォーマットに従う。与えられる数は全て整数である。
$N$
$c_{1,1}$ $c_{1,2}$ $...$ $c_{1,N}$
$c_{2,1}$ $c_{2,2}$ $...$ $c_{2,N}$
$...$
$c_{N,1}$ $c_{N,2}$ $...$ $c_{N,N}$
制約
$2 \leq N \leq 8$
$0 \leq c_{i,j} \leq 10^5$
$c_{i,j} = c_{j,i}$
$c_{i,i} = 0$
出力
最大値を1行に出力せよ。
Sample Input 1
3
0 1 3
1 0 8
3 8 0
Output for the Sample Input 1
5
もっとも必要コストが大きい順列は$\{1,3,2\}$で、
1,2を入れ替えて$\{2,3,1\}$とする。
1,3を入れ替えて$\{2,1,3\}$とする。
1,2を入れ替えて$\{1,2,3\}$とする。
以上の操作によりコスト5でソートでき、またこれが最善であることが証明できる。
他の順列もコスト5以下でソートできることを示すことができる。

Submitted solutions:

code_snippet: // #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;

#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
typedef pair<int, int> pii;
typedef long long ll;
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

map< vector<int>, int > rec;

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

    using State = pair< int, vector<int> >;
    priority_queue< State, vector<State>, greater<> > que;
    vector<int> init(N);
    iota(init.begin(), init.end(), 0LL);
    rec[init] = 0;
    que.push(make_pair(0, init));

    int ans = 0;
    while(que.size()) {
        int cost; vector<int> vec; tie(cost, vec) = que.top(); que.pop();

        if(rec[vec] < cost) continue;
        for(int i=0; i<N; i++) {
            for(int j=i+1; j<N; j++) {
                swap(vec[i], vec[j]);

                if(!rec.count(vec) or rec[vec] > cost + c[i][j]) {
                    rec[vec] = cost + c[i][j];
                    que.emplace(cost + c[i][j], vec);
                }
                
                swap(vec[i], vec[j]);
            }
        }
    }
    for(auto e : rec) ans = max(ans, e.second);
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 480
memory_kb: 15340
final_rank: 6

code_snippet: #include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
#define chmin(a, b) ((a)=min((a), (b)))
#define chmax(a, b) ((a)=max((a), (b)))
#define fs first
#define sc second
#define eb emplace_back
using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef tuple<int, int, int> T;

const ll MOD=1e9+7;
const ll INF=1e18;
const double pi=acos(-1);
const double eps=1e-10;

int dx[]={1, 0, -1, 0};
int dy[]={0, -1, 0, 1};

const int MAX_V = 41000;

vector<vector<P>> G(MAX_V);
vector<int> dist(MAX_V, 1e9);
void dijkstra(int s){
    priority_queue<P, vector<P>, greater<P>> que;
    dist[s] = 0;
    que.push(P(0, s));

    while(!que.empty()){
        int ccost, cv;
        tie(ccost, cv) = que.top();
        que.pop();

        if(dist[cv] < ccost) continue;

        for(auto x : G[cv]){
            int nv = x.first;
            int ncost = x.second;
            if(dist[cv] + ncost < dist[nv]){
                dist[nv] = dist[cv] + ncost;
                que.push(P(dist[nv], nv));
            }
        }
    }
}

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

    vector<int> v(n);
    iota(v.begin(), v.end(), 0);

    map<vector<int>, int> node;
    int cnt = 0;
    do{
        node[v] = cnt++; 
    }while(next_permutation(v.begin(), v.end()));

    sort(v.begin(), v.end());

    do{
        int cv = node[v];
        for(int i=0; i<n; i++){
            for(int j=i+1; j<n; j++){
                swap(v[i], v[j]);
                int nv = node[v];
                G[cv].push_back(P(nv, c[v[i]][v[j]]));
                G[nv].push_back(P(cv, c[v[i]][v[j]]));
                swap(v[i], v[j]);
            }
        }
    }while(next_permutation(v.begin(), v.end()));

    dijkstra(0);

    int ans = 0;
    for(int i=0; i<cnt; i++){
        ans = max(ans, dist[i]);
    }

    cout << ans << endl;
}
accuracy: 1
time_ms: 270
memory_kb: 31748
final_rank: 9

code_snippet: #include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>

using namespace std;

const int INF = 1001001001;
const int MOD = 1000000007;


vector<int> dijk(int s, int v, vector<vector<pair<int, int> > > adjlist){
    
    priority_queue <pair<int, int> > wait;
    vector<int> result(v, INF);

    //スタート地点を追加
    result[s] = 0;
    wait.push(make_pair(0, s));

    //ダイクストラ本体
    while(!wait.empty()){    //waitが空になるまで

        int nowpoint = wait.top().second;
        int nowcost = -wait.top().first;
        wait.pop();

        if(result[nowpoint] < nowcost) continue;

        //今いる頂点と隣接しているすべての頂点をなめる
        for(int i = 0; i < adjlist[nowpoint].size(); i++){

            int nextpoint = adjlist[nowpoint][i].second;
            int nextcost = nowcost + adjlist[nowpoint][i].first;
            //現時点より安く到達できそうであれば、結果を更新して優先度付きキューに格納
            if(result[nextpoint] > nextcost){
                result[nextpoint] = nextcost;
                wait.push(make_pair(-nextcost, nextpoint));
            }
        }
    }
    
    return result;         //結果列を返す
}

signed main(){
    
    int n; cin >> n;
    vector<vector<int> > c(n, vector<int> (n));
    for(int i = 0; i < n; i++) for(int j = 0; j < n; j++) cin >> c[i][j];
    map<vector<int>, int> m;
    int cnt = 0;
    vector<int> v(n);
    for(int i = 0; i < n; i++){
        v[i] = i;
    }

    do{
        m[v] = cnt;
        cnt++;
    }while(next_permutation(v.begin(), v.end()));
    

    vector<vector<pair<int, int> > > G(cnt);
    sort(v.begin(), v.end());


    do{
        int cur = m[v];
        for(int i = 0; i < n; i++){
            for(int j = i; j < n; j++){
                swap(v[i], v[j]);
                int cost = c[v[i]][v[j]];
                int nxt = m[v];
                G[cur].push_back({cost, nxt});
                G[nxt].push_back({cost, cur});
                swap(v[i], v[j]);
            }
        }

    }while(next_permutation(v.begin(), v.end()));

    vector<int> result = dijk(0, cnt, G);
    int ans = 0;
    for(int i = 0; i < cnt; i++){
        ans = max(ans, result[i]);
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 340
memory_kb: 75316
final_rank: 16

code_snippet: #include <cstdio>
#include <cstdint>
#include <vector>
#include <algorithm>
#include <utility>
#include <queue>
#include <tuple>
#include <numeric>
#include <functional>
#include <map>

template <class Weight>
struct edge {
  using value_type = Weight;
  size_t src, dst;
  value_type cost;
  edge(size_t src, size_t dst, value_type cost = 1): src(src), dst(dst), cost(cost) {}
};

template <class Weight>
struct graph: public std::vector<std::vector<edge<Weight>>> {
  using value_type = Weight;
  graph(size_t n): std::vector<std::vector<edge<value_type>>>(n) {}

  void connect_with(size_t src, size_t dst, value_type cost = 1) {
    (*this)[src].emplace_back(src, dst, cost);
    (*this)[dst].emplace_back(dst, src, cost);
  }
};

template <class Tp>
constexpr Tp inf = Tp(1) << (8*sizeof(Tp)-3);

template <class Tp, class Compare>
using priority_queue = std::priority_queue<Tp, std::vector<Tp>, Compare>;

template <class Weight>
std::vector<Weight> shortest(const graph<Weight>& g, size_t s) {
  std::vector<Weight> res(g.size(), inf<Weight>);
  priority_queue<std::pair<Weight, size_t>, std::greater<>> q;
  res[0] = 0;
  q.emplace(0, s);
  while (!q.empty()) {
    Weight w;
    size_t v;
    std::tie(w, v) = q.top();
    q.pop();
    if (w > res[v]) continue;

    for (const auto& e: g[v]) {
      if (res[e.dst] > w + e.cost) {
        res[e.dst] = w + e.cost;
        q.emplace(res[e.dst], e.dst);
      }
    }
  }
  return res;
}

int main() {
  size_t N;
  scanf("%zu", &N);

  std::vector<std::vector<int>> c(N, std::vector<int>(N));
  for (auto& ci: c)
    for (auto& cij: ci)
      scanf("%d", &cij);

  std::vector<size_t> ind(N);
  std::iota(ind.begin(), ind.end(), 0);

  std::map<std::vector<size_t>, size_t> enc;
  {
    size_t i = 0;
    do {
      enc[ind] = i++;
    } while (std::next_permutation(ind.begin(), ind.end()));
  }

  graph<int> g(enc.size());

  do {
    size_t s = enc[ind];
    for (size_t i = 0; i < N; ++i) {
      for (size_t j = 0; j < i; ++j) {
        size_t u = ind[i];
        size_t v = ind[j];
        int cost = c[u][v];

        std::swap(ind[u], ind[v]);
        size_t t = enc[ind];
        std::swap(ind[u], ind[v]);
        g.connect_with(s, t, cost);
      }
    }
  } while (std::next_permutation(ind.begin(), ind.end()));

  auto res = shortest(g, 0);
  printf("%d\n", *std::max_element(res.begin(), res.end()));
}
accuracy: 1
time_ms: 290
memory_kb: 75264
final_rank: 15

code_snippet: // #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;

#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
typedef pair<int, int> pii;
typedef long long ll;
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

map< vector<int>, int > memo;

struct Elem {
    vector<int> vec;
    int cost;
    Elem() {}
    Elem(vector<int> v, int c) : vec(v), cost(c) {}
    bool operator<(const Elem &e) const {
        return cost > e.cost;
    }
};

int cost[10][10];
signed main() {
    int N; cin >> N;
    for(int i=0; i<N; i++) {
        for(int j=0; j<N; j++) {
            cin >> cost[i][j];
        }
    }

    priority_queue<Elem> que;
    vector<int> init(N);
    iota(init.begin(), init.end(), 0);
    memo[init] = 0;
    que.push(Elem(init, 0));
    
    while(que.size()) {
        auto e = que.top(); que.pop();
        auto vec = e.vec;
        auto orig = e.cost;
        if(orig > memo[vec]) continue;

        for(int i=0; i<N; i++) {
            for(int j=i+1; j<N; j++) {
                int vl = vec[i], vr = vec[j];
                int c = cost[vl][vr];

                swap(vec[i], vec[j]);
                if(!memo.count(vec) or memo[vec] > orig + c) {
                    memo[vec] = orig + c;
                    que.push(Elem(vec, orig + c));
                }
                swap(vec[i], vec[j]);
            }
        }
    }

    int ans = 0;
    for(auto v : memo) ans = max(ans, v.second);
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 540
memory_kb: 15152
final_rank: 7

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;


#define NUM 9

struct Info{
	Info(int arg_code,int arg_sum_cost){
		code = arg_code;
		sum_cost = arg_sum_cost;
	}
	bool operator<(const struct Info &arg) const{ //総コストの昇順(PQ)
		return sum_cost > arg.sum_cost;
	}
	int code,sum_cost;
};

int N;
int table_index;
int table[40320][8],min_cost[40320];
int work[NUM],change_cost[NUM][NUM];
bool check[NUM];
map<int,int> MAP;

//N!の順列を作る
void makeCode(int index){

	if(index == N){

		int tmp = 0;

		for(int i = 0; i < N; i++){
			tmp = 10*tmp+work[i];
			table[table_index][i] = work[i];
		}

		MAP[tmp] = table_index;
		table_index++;

		return;
	}

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

		if(check[i])continue;
		check[i] = true;
		work[index] = i;
		makeCode(index+1);
		check[i] = false;
	}
}

int main(){

	scanf("%d",&N);

	for(int i = 1; i <= N; i++){
		for(int k = 1; k <= N; k++){
			scanf("%d",&change_cost[i][k]);
		}
	}

	//順列テーブルを作成する
	table_index = 0;
	for(int i = 1; i <= N; i++)check[i] = false;

	for(int i = 1; i <= N; i++){
		check[i] = true;
		work[0] = i;
		makeCode(1);
		check[i] = false;
	}

	//整列された状態を作る
	int first = 0,first_code;

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

		first = 10*first+i;
	}
	first_code = MAP[first];

	priority_queue<Info> Q;

	for(int i = 0; i < table_index; i++)min_cost[i] = BIG_NUM;

	min_cost[first_code] = 0;
	Q.push(Info(first_code,0));

	int next_num,next_code,next_cost;

	//整列された状態からの最短コストを求める
	while(!Q.empty()){

		if(Q.top().sum_cost > min_cost[Q.top().code]){
			Q.pop();
		}else{

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

				work[i] = table[Q.top().code][i];
			}

			for(int i = 0; i < N-1; i++){ //交換する左側
				for(int k = i+1; k < N; k++){ //右

					next_cost = Q.top().sum_cost+change_cost[work[i]][work[k]];
					swap(work[i],work[k]);
					next_num = 0;
					for(int a = 0; a < N; a++){
						next_num = 10*next_num+work[a];
					}
					next_code = MAP[next_num];
					swap(work[i],work[k]); //元に戻す

					if(min_cost[next_code] > next_cost){

						min_cost[next_code] = next_cost;
						Q.push(Info(next_code,next_cost));
					}
				}
			}
			Q.pop();
		}
	}

	int ans = 0;
	for(int i = 0; i < table_index; i++){
		ans = max(ans,min_cost[i]);
	}

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

	return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 6792
final_rank: 2

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;

using ld= long double;

struct aa {
	vector<int>v;
	int cost;
};
class Compare {
public:
	bool operator()(const aa&l, const aa&r) {
		return l.cost>r.cost;
	}
};

int main() {
	int N;cin>>N;
	vector<vector<int>>field(N,vector<int>(N));
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < N; ++j) {
			int a;cin>>a;
			field[i][j]=a;
		}
	}
	priority_queue<aa,vector<aa>,Compare>que;
	vector<int>start(N);
	iota(start.begin(),start.end(),0);
	que.push(aa{ start,0 });
	map<vector<int>,int>memo;
	memo[start]=0;
	while (!que.empty()) {
		auto atop(que.top());
		que.pop();
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j < N; ++j) {
				auto nv(atop.v);
				swap(nv[i],nv[j]);
				if (memo.find(nv) == memo.end()) {
					memo[nv]=1e9;
				}
				if (memo[nv] > atop.cost + field[i][j]) {
					memo[nv]=atop.cost+field[i][j];
					que.push(aa{ nv,atop.cost + field[i][j] });
				}
			}
		}
	}
	int ans=0;
	for (auto m : memo) {
		ans=max(ans,m.second);
	}
	cout<<ans<<endl;
	
	
	return 0;
}
accuracy: 1
time_ms: 1910
memory_kb: 12552
final_rank: 14

code_snippet: #include<iostream>
#include<queue>
using namespace std;
int dp[16434825], x[8][8]; queue<int>Q;
int main() {
	int n; cin >> n; int minp = 0, maxp = 0; for (int i = 0; i < n; i++) { minp += (n - 1 - i)*(1 << (3 * i)); maxp += i*(1 << (3 * i)); }
	for (int i = minp; i <= maxp; i++)dp[i] = 1000000007;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++)cin >> x[i][j];
	}
	int G = 0, maxn = 0; for (int i = 0; i < n; i++) { G += (1 << (3 * i))*i; }Q.push(G); dp[G] = 0;
	while (!Q.empty()) {
		int H = Q.front(); Q.pop(); int I[8], J[8]; for (int i = 0; i < 8; i++)I[i] = (H / (1 << (3 * i))) % 8;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int k = 0; k < 8; k++)J[k] = I[k];
				swap(J[i], J[j]); int K = 0;
				for (int k = 0; k < 8; k++)K += (1 << (3 * k))*J[k];
				if (dp[K] > dp[H] + x[i][j]) { dp[K] = dp[H] + x[i][j]; Q.push(K); }
			}
		}
	}
	for (int i = minp; i <= maxp; i++) { if (dp[i] != 1000000007 && maxn < dp[i])maxn = dp[i]; }
	cout << maxn << endl;
	return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 64216
final_rank: 13

code_snippet: #include<iostream>
#include<queue>
using namespace std;
int dp[1 << 24], x[8][8]; queue<int>Q;
int main() {
	int n; cin >> n; int minp = 0, maxp = 0; for (int i = 0; i < n; i++) { minp += (n - 1 - i)*(1 << (3 * i)); maxp += n*(1 << (3 * i)); }
	for (int i = minp; i <= maxp; i++)dp[i] = 1000000007;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++)cin >> x[i][j];
	}
	int G = 0, maxn = 0; for (int i = 0; i < n; i++) { G += (1 << (3 * i))*i; }Q.push(G); dp[G] = 0;
	while (!Q.empty()) {
		int H = Q.front(); Q.pop(); int I[8], J[8]; for (int i = 0; i < 8; i++)I[i] = (H / (1 << (3 * i))) % 8;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				for (int k = 0; k < 8; k++)J[k] = I[k];
				swap(J[i], J[j]); int K = 0;
				for (int k = 0; k < 8; k++)K += (1 << (3 * k))*J[k];
				if (dp[K] > dp[H] + x[i][j]) { dp[K] = dp[H] + x[i][j]; Q.push(K); }
			}
		}
	}
	for (int i = minp; i <= maxp; i++) { if (dp[i] != 1000000007 && maxn < dp[i])maxn = dp[i]; }
	cout << maxn << endl;
	return 0;
}
accuracy: 0.016666666666666666
time_ms: 40
memory_kb: 65332
final_rank: 20

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

using namespace std;

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

#define INF (1e9)

int main() {

  int N; cin >> N;
  vector<vector<int>> v(N, vector<int>(N));
  rep(i, N) rep(j, N) {
    cin >> v[i][j];
  }
  
  vector<int> V(N);
  iota(V.begin(), V.end(), 0);
  
  priority_queue<pair<int, vector<int>>,
		 vector<pair<int, vector<int>>>,
		 greater<pair<int, vector<int>>>> q;
  map<vector<int>, int> mp;
  mp[V] = 0;
  q.emplace(0, V);
  while(!q.empty()) {
    int co; vector<int> V; tie(co, V) = q.top(); q.pop();
    
    rep(i, N) REP(j, i+1, N) {
      swap(V[i], V[j]);
      if(mp.find(V) != mp.end() && mp[V] <= co + v[V[i]][V[j]]) {
	swap(V[i], V[j]);
	continue;
      }

      mp[V] = co + v[V[i]][V[j]];
      q.emplace(co + v[V[i]][V[j]], V);
      swap(V[i], V[j]);
    }
  }
  
  int ans = 0;
  
  for(auto && e: mp) {
    ans = max(ans, e.second);
  }

  cout << ans << endl;
  
  return 0;
}
accuracy: 1
time_ms: 930
memory_kb: 12440
final_rank: 10

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

using namespace std;

typedef long long ll;
typedef vector<int> Vec;

struct State {
    ll cost;
    Vec v;
    State(ll cost, Vec v) :
        cost(cost), v(v) {}

    bool operator < (const State &s) const {
        return cost > s.cost;
    }
};

ll get_val(Vec &v)
{
    ll res = 0LL, N = v.size();
    for (auto &x: v) {
        res *= N;
        res += x;
    }
    return res;
}

int main()
{
    int N;
    cin >> N;
    ll c[N][N];
    Vec start(N);
    for (int i = 0; i < N; i++) {
        start[i] = i;
        for (int j = 0; j < N; j++) {
            cin >> c[i][j];
        }
    }

    priority_queue<State> Q;
    Q.push(State(0, start));

    unordered_map<ll, ll> min_cost;
    min_cost[get_val(start)] = 0;    
    
    while (!Q.empty()) {
        State s = Q.top(); Q.pop();
        Vec v = s.v;
        
        for (int i = 0; i < N; i++) {
            for (int j = i+1; j < N; j++) {
                swap(v[i], v[j]);
                ll vv = get_val(v);
                if (min_cost.count(vv) == 0 ||
                    s.cost + c[i][j] < min_cost[vv]) {
                    min_cost[vv] = s.cost + c[i][j];
                    Q.push(State(min_cost[vv], v));
                }                    
                swap(v[i], v[j]);
            }
        }        
    }

    ll res = 0;
    for (auto &x: min_cost) {
        res = max(res, x.second);
    }    
    cout << res << endl;    
    return 0;
}
accuracy: 1
time_ms: 230
memory_kb: 9108
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(c) (c).begin(),(c).end()
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define REP(i,m,n) for(int i=(int)(m);i<(int)(n);i++)
#define rep(i,n) REP(i,0,n)
#define iter(c) __typeof((c).begin())
#define tr(it,c) for(iter(c) it=(c).begin();it!=(c).end();it++)
#define mem(a) memset(a,0,sizeof(a))
#define pd(a) printf("%.10f\n",a)
#define pb(a) push_back(a)
#define in(a) insert(a)
#define pi M_PI
#define R cin>>
#define F first
#define S second
#define C class
#define ll long long
#define ln cout<<'\n'
template<C T>void pr(T a){cout<<a;ln;}
template<C T,C T2>void pr(T a,T2 b){cout<<a<<' '<<b;ln;}
template<C T,C T2,C T3>void pr(T a,T2 b,T3 c){cout<<a<<' '<<b<<' '<<c;ln;}
template<C T>void PR(T a,int n){rep(i,n){if(i)cout<<' ';cout<<a[i];}ln;}
bool check(int n,int m,int x,int y){return x>=0&&x<n&&y>=0&&y<m;}
const ll MAX=1000000007,MAXL=1LL<<60,dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
typedef pair<ll,vector<int> > P;

void Main() {
  int n;
  R n;
  ll c[n][n];
  rep(i,n)rep(j,n)R c[i][j];
  vector<int> v(n);
  rep(i,n) v[i]=i;
  map<vector<int>,int> m;
  m[v]=0;
  priority_queue<P,vector<P>,greater<P> > que;
  que.push(P(0,v));
  ll ans=0;
  while(!que.empty()) {
    P p=que.top();que.pop();
    ll cc=p.F;
    vector<int> a=p.S;
    if(m[a]<cc) continue;
    ans=max(ans,cc);
    rep(i,n) {
      REP(j,i+1,n) {
        vector<int> b=a;
        swap(b[i],b[j]);
        if(!m.count(b)||m[b]>cc+c[i][j]) {
          m[b]=cc+c[i][j];
          que.push(P(cc+c[i][j],b));
        }
      }
    }
  }
  pr(ans);
}

int main() {
  ios::sync_with_stdio(0);cin.tie(0);
  Main();return 0;
}
accuracy: 1
time_ms: 540
memory_kb: 10796
final_rank: 5

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

using namespace std;

typedef long long ll;
typedef vector<int> Vec;

struct State {
    ll cost;
    Vec v;
    State(ll cost, Vec v) :
        cost(cost), v(v) {}

    bool operator < (const State &s) const {
        return cost > s.cost;
    }
};

int main()
{
    int N;
    cin >> N;
    ll c[N][N];
    Vec start(N);
    for (int i = 0; i < N; i++) {
        start[i] = i;
        for (int j = 0; j < N; j++) {
            cin >> c[i][j];
        }
    }

    priority_queue<State> Q;
    Q.push(State(0, start));

    map<Vec, ll> min_cost;
    min_cost[start] = 0;
    
    while (!Q.empty()) {
        State s = Q.top(); Q.pop();
        Vec v = s.v;
        
        for (int i = 0; i < N; i++) {
            for (int j = i+1; j < N; j++) {
                swap(v[i], v[j]);
                if (min_cost.count(v) == 0 ||
                    s.cost + c[i][j] < min_cost[v]) {
                    min_cost[v] = s.cost + c[i][j];
                    Q.push(State(min_cost[v], v));
                }                    
                swap(v[i], v[j]);
            }
        }        
    }

    ll res = 0;
    for (auto &x: min_cost) {
        res = max(res, x.second);
    }
    
    cout << res << endl;    
    return 0;
}
accuracy: 1
time_ms: 1130
memory_kb: 12440
final_rank: 12

code_snippet: #include <map>
#include <queue>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int n, c[8][8]; map<vector<char>, int> m;
int main() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			scanf("%d", &c[i][j]);
		}
	}
	vector<char> s; for (int i = 0; i < n; i++) s.push_back((char)(i));
	priority_queue<pair<int, vector<char> > > que; que.push(make_pair(-1, s));
	int ret = 0;
	while (!que.empty()) {
		pair<int, vector<char> > state = que.top(); que.pop();
		vector<char> v = state.second;
		if (m[v] != 0) continue;
		m[v] = state.first;
		ret = -state.first - 1;
		for (int i = 0; i < n; i++) {
			for (int j = i + 1; j < n; j++) {
				swap(v[i], v[j]);
				que.push(make_pair(state.first - c[i][j], v));
				swap(v[i], v[j]);
			}
		}
	}
	printf("%d\n", ret);
	return 0;
}
accuracy: 1
time_ms: 1030
memory_kb: 58876
final_rank: 17

code_snippet: #include <map>
#include <queue>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
int n, c[8][8]; vector<int> p; map<vector<char>, int> m;
int main() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			scanf("%d", &c[i][j]);
		}
	}
	vector<char> s; for (int i = 0; i < n; i++) s.push_back((char)(i));
	priority_queue<pair<int, vector<char> > > que; que.push(make_pair(-1, s));
	while (!que.empty()) {
		pair<int, vector<char> > state = que.top(); que.pop();
		vector<char> v = state.second;
		if (m[v] != 0) continue;
		m[v] = state.first;
		for (int i = 0; i < n; i++) {
			for (int j = i + 1; j < n; j++) {
				swap(v[i], v[j]);
				que.push(make_pair(state.first - c[i][j], v));
				swap(v[i], v[j]);
			}
		}
	}
	int ret = 0;
	for (map<vector<char>, int>::iterator i = m.begin(); i != m.end(); i++) {
		ret = max(ret, -(*i).second - 1);
	}
	printf("%d\n", ret);
	return 0;
}
accuracy: 1
time_ms: 1040
memory_kb: 58944
final_rank: 18

code_snippet: /*
 * 2361.cc: Sort
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 8;

/* typedef */

typedef long long ll;
typedef pair<ll,int> pli;
typedef map<int,ll> mil;

/* global variables */

int cs[MAX_N][MAX_N];
mil dists;

/* subroutines */

inline int getb(int bits, int k) {
  return (bits >> (3 * k)) & 7;
}

inline int setb(int bits, int k, int v) {
  return (bits & ~(7 << (3 * k))) | (v << (3 * k));
}

/* main */

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

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

  int st = 0;
  for (int i = 0; i < n; i++) st = setb(st, i, i);
  //printf("%x\n", st);

  dists[st] = 0;

  priority_queue<pli,vector<pli>,greater<pli> > q;
  q.push(pli(0, st));

  while (! q.empty()) {
    pli u = q.top(); q.pop();
    ll &ud = u.first;
    int &ui = u.second;
    if (ud != dists[ui]) continue;

    for (int i = 0; i < n; i++) {
      int bi = getb(ui, i);
      for (int j = i + 1; j < n; j++) {
	int bj = getb(ui, j);
	int vi = setb(setb(ui, i, bj), j, bi);
	ll vd = ud + cs[i][j];

	mil::iterator mit = dists.find(vi);
	if (mit == dists.end()) {
	  dists[vi] = vd;
	  q.push(pli(vd, vi));
	}
	else if (mit->second > vd) {
	  mit->second = vd;
	  q.push(pli(vd, vi));
	}
      }
    }
  }

  ll maxd = 0;
  for (mil::iterator mit = dists.begin(); mit != dists.end(); mit++)
    if (maxd < mit->second) maxd = mit->second;

  printf("%lld\n", maxd);
  return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 4524
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <queue>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<30
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

struct D {
	vector<int> v;
	int cost;

	D(vector<int> t, int c) {
		v.clear();
		copy(t.begin(),t.end(),back_inserter(v));
		cost = c;
	}

	bool operator < (const D &data) const {
		return cost < data.cost;
	}

	bool operator > (const D &data) const {
		return cost > data.cost;
	}
};

int n, cost[10][10];
map< vector<int> , int> m;

void dijkstra() {
	priority_queue<D ,vector<D>, greater<D> > que;

	vector<int> t(n);
	rep(i, n) t[i] = i;

	que.push(D(t, 0));
	m[t] = 0;

	while(que.size()) {
		D data = que.top();
		que.pop();

		vector<int> v = data.v;
		int c = data.cost;


		if(m[v] < c) continue;

		rep(i, v.size()) {
			REP(j, i+1, v.size()) {
				vector<int> t2(v.begin(), v.end());
				swap(t2[i], t2[j]);
				int nc = c + cost[i][j];

				if(m[t2] > nc) {
					m[t2] = nc;
					que.push(D(t2, nc));
				}
			}
		}
	}
}

int main() {
	cin >> n;

	memset(cost, 0, sizeof(cost));
	rep(i, n) {
		rep(j, n) cin >> cost[i][j];
	}

	vector<int> v(n);
	rep(i, n) v[i] = i;

	do {
		m[v] = INF;

	}while(next_permutation(v.begin(), v.end()));

	dijkstra();

	int ans = 0;
	map< vector<int>, int>::iterator ite;
	for(ite = m.begin(); ite != m.end(); ite++) {
		ans = max(ans, ite->second);
		// rep(i, ite->first.size()) cout << ite->first[i] << " ";
		// cout << " c:" << ite->second << endl;
	}

	cout << ans << endl;

	return 0;
}
accuracy: 1
time_ms: 480
memory_kb: 12148
final_rank: 4

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <map>
#include <set>
#include <queue>

#define REP(i,k,n) for(int i=k;i<n;i++)
#define rep(i,n) for(int i=0;i<n;i++)
#define INF 1<<30
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int,int> P;

struct D {
	vector<int> v;
	int cost;

	D(vector<int> t, int c) {
		v.clear();
		copy(t.begin(),t.end(),back_inserter(v));
		cost = c;
	}

	bool operator < (const D &data) const {
		return cost < data.cost;
	}

	bool operator > (const D &data) const {
		return cost > data.cost;
	}
};

int n, cost[10][10];
map< vector<int> , int> m;

void dijkstra() {
	priority_queue<D ,vector<D>, greater<D> > que;

	vector<int> t(n);
	rep(i, n) t[i] = i;
	que.push(D(t, 0));

	int cnt = 0;

	while(que.size()) {
		D data = que.top();
		que.pop();

		vector<int> v = data.v;
		int c = data.cost;


		if(m[v] < c) continue;

		rep(i, v.size()) {
			REP(j, i+1, v.size()) {
				vector<int> t2(v.begin(), v.end());
				swap(t2[i], t2[j]);
				int nc = c + cost[i][j];

				if(m[t2] > nc) {
					m[t2] = nc;
					que.push(D(t2, nc));
				}
			}
		}
	}
}

int main() {
	cin >> n;

	memset(cost, 0, sizeof(cost));
	rep(i, n) {
		rep(j, n) cin >> cost[i][j];
	}

	vector<int> v(n);
	rep(i, n) v[i] = i;

	do {
		m[v] = INF;

	}while(next_permutation(v.begin(), v.end()));

	dijkstra();

	int ans = 0;
	map< vector<int>, int>::iterator ite;
	for(ite = m.begin(); ite != m.end(); ite++) {
		ans = max(ans, ite->second);
	}

	cout << ans << endl;

	return 0;
}
accuracy: 0.05
time_ms: 470
memory_kb: 11160
final_rank: 19

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

const int INF = 1<<29;

struct state{
    vector<int> arr;
    int cost;
    state(){}
    ~state(){}
    state(vector<int> a, int c){
        arr.resize(a.size());
        for(int i = 0; i < a.size(); i++){
            arr[i] = a[i];
        }
        cost = c;
    }
};

int N;
int c[8][8];
map<vector<int>, int> ord;
int d[50000];

void set_ord(int n){
    vector<int> vec(n);
    for(int i = 0; i < n; i++){
        vec[i] = i;
    }
    int m = 0;
    do{
        ord[vec] = m++;
    }while(next_permutation(vec.begin(), vec.end()));
}

int main(){
    scanf("%d", &N);
    set_ord(N);
    for(int i = 0; i < N; i++){
        for(int j = 0; j < N; j++){ scanf("%d", &c[i][j]); }
    }
    vector<int> init(N);
    for(int i = 0; i < N; i++){ init[i] = i; }
    fill(d, d+50000, INF);
    queue<state> que;
    que.push(state(init, 0));
    d[ord[init]] = 0;
    while(!que.empty()){
        state s = que.front(); que.pop();
        vector<int>& v = s.arr;
        int ind = ord[v];
        if(s.cost > d[ind]) continue;
        for(int i = 0; i < N; i++){
            for(int j = i+1; j < N; j++){
                swap(v[i], v[j]);
                if(d[ind] + c[v[i]][v[j]] < d[ord[v]]){
                    d[ord[v]] = d[ind] + c[v[i]][v[j]];
                    que.push(state(v, d[ord[v]]));
                }
                swap(v[i], v[j]);
            }
        }
    }
    int max_v = 0;
    for(int i = 0; i < 50000; i++){
        if(d[i] == INF) continue;
        max_v = max(max_v, d[i]);
    }
    printf("%d\n", max_v);
    return 0;
}
accuracy: 1
time_ms: 1130
memory_kb: 11824
final_rank: 11

code_snippet: #include <cassert>// c
#include <iostream>// io
#include <iomanip>
#include <fstream>
#include <sstream>
#include <vector>// container
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <algorithm>// other
#include <complex>
#include <numeric>
#include <functional>
#include <random>
#include <regex>
using namespace std;

typedef long long ll;

#define ALL(c) (begin(c)),(end(c))
#define REP(i,n) FOR(i,0,n)
#define REPr(i,n) FORr(i,0,n)
#define FOR(i,l,r) for(int i=(int)(l);i<(int)(r);++i)
#define FORr(i,l,r) for(int i=(int)(r)-1;i>=(int)(l);--i)
#define EACH(it,o) for(auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l,v,r) ((l)<=(v) && (v)<(r))
#define UNIQUE(v) v.erase(unique(ALL(v)),v.end())
//debug
#define DUMP(x)  cerr << #x << " = " << (x)
#define LINE()    cerr<< " (L" << __LINE__ << ")"

class range {
private:
    struct Iter{
        int v;
        int operator*(){return v;}
        bool operator!=(Iter& itr) {return v < itr.v;}
        void operator++() {++v;}
    };
    Iter i, n;
public:
    range(int n) : i({0}), n({n}) {}
    range(int i, int n) : i({i}), n({n}) {}
    Iter& begin() {return i;}
    Iter& end() {return n;}
};

//output
template<typename T> ostream& operator << (ostream& os, const vector<T>& as){REP(i,as.size()){if(i!=0)os<<" "; os<<as[i];}return os;}
template<typename T> ostream& operator << (ostream& os, const vector<vector<T>>& as){REP(i,as.size()){if(i!=0)os<<endl; os<<as[i];}return os;}
template<typename T> ostream& operator << (ostream& os, const set<T>& ss){for(auto a:ss){if(a!=ss.begin())os<<" "; os<<a;}return os;}
template<typename T1,typename T2> ostream& operator << (ostream& os, const pair<T1,T2>& p){os<<p.first<<" "<<p.second;return os;}
template<typename K,typename V> ostream& operator << (ostream& os, const map<K,V>& m){bool isF=true;for(auto& p:m){if(!isF)os<<endl;os<<p;isF=false;}return os;}
template<typename T1> ostream& operator << (ostream& os, const tuple<T1>& t){os << get<0>(t);return os;}
template<typename T1,typename T2> ostream& operator << (ostream& os, const tuple<T1,T2>& t){os << get<0>(t)<<" "<<get<1>(t);return os;}
template<typename T1,typename T2,typename T3> ostream& operator << (ostream& os, const tuple<T1,T2,T3>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5,T6>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t)<<" "<<get<5>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6,typename T7> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t)<<" "<<get<5>(t)<<" "<<get<6>(t);return os;}

//input
char tmp[1000];
#define nextInt(n) scanf("%d",&n)
#define nextLong(n) scanf("%lld",&n) //I64d
#define nextDouble(n) scanf("%lf",&n) 
#define nextChar(n) scanf("%c",&n)
#define nextString(n) scanf("%s",tmp);n=tmp

// values
template<typename T> T INF(){assert(false);};
template<> int INF<int>(){return 1<<28;};
template<> ll INF<ll>(){return 1LL<<58;};
template<> float INF<float>(){return 1e10;};
template<> double INF<double>(){return 1e16;};
template<> long double INF<long double>(){return 1e16;};

template<class T> T EPS(){assert(false);};
template<> int EPS<int>(){return 1;};
template<> ll EPS<ll>(){return 1LL;};
template<> float EPS<float>(){return 1e-8;};
template<> double EPS<double>(){return 1e-8;};
template<> long double EPS<long double>(){return 1e-8;};

template<typename T,typename U> T pmod(T v,U M){return (v%M+M)%M;}


namespace EGraph{
    typedef ll Cost;Cost CINF=INF<Cost>();
    struct Edge{
        int from,to;Cost cost;
        Edge(int from,int to,Cost cost)
        : from(from),to(to),cost(cost) {};
        bool operator<(Edge r) const{ return cost<r.cost;}
        bool operator>(Edge r) const{ return cost>r.cost;}
    };
    typedef vector<vector<Edge> >  Graph;
}
using namespace EGraph;

namespace ShortestPath{
    using namespace EGraph;

    struct Task{
        int prev,pos;Cost cost;
        Task(int prev,int pos,Cost cost)
            :prev(prev),pos(pos),cost(cost){};
        bool operator>(const Task& r) const{ return cost > r.cost;}
    };

    //verified by codoforces 144D http://codeforces.com/contest/144/submission/4976825
    // // 負の辺がない
    // // O(E*logV)
    vector<Cost> dijkstra(const Graph& g,const int s,vector<int>& prev){
        const int V=g.size();
        vector<Cost> d(V,CINF);d[s]=0;
        fill(ALL(prev), -2);
        
        priority_queue<Task,vector<Task>,greater<Task> > que;que.push(Task(-1,s,0));// [ ,e,,f, ] <=> e.cost < e.cost
        vector<bool> visited(V);
        while(!que.empty()){
            Task task=que.top();que.pop();
            if(visited[task.pos])continue;
            visited[task.pos]=true;
            prev[task.pos]=task.prev;
            EACH(e,g[task.pos])if(d[e->to]>d[e->from]+e->cost){
                d[e->to]=d[e->from]+e->cost;
                que.push(Task(e->from,e->to,d[e->to]));
            }   
        }
        return d;
    }
    vector<Cost> dijkstra(const Graph& g,const int s){
        vector<int> prev(g.size());return dijkstra(g,s,prev);
    }
}
using namespace ShortestPath;

class Main{
    public:

    int N;
    vector<vector<int>> cs;
        
    map<vector<short>,int> enc;
    // map<int,vector<int>> dec;
    
    void run(){
        cin >> N;
        cs=vector<vector<int>>(N,vector<int>(N));
        REP(y,N)REP(x,N)cin >> cs[y][x];

        vector<short> per(N);iota(ALL(per),0);
        int ind=0;
        do{
            enc[per]=ind;
            // dec[ind]=per;
            int te=0;REP(i,N)for(int j=i+1;j<N;j++)if(per[i]>per[j])te++;
            ind++;
        }while(next_permutation(ALL(per)));
        
        Graph g(ind);
        int code=0;iota(ALL(per),0);
        do{
            REP(i,N)for(int j=i+1;j<N;j++){
                swap(per[i],per[j]);
                int ncode=enc[per];
                g[code].push_back(Edge(code,ncode,cs[per[i]][per[j]]));
                 swap(per[i],per[j]);
            }
            code++;
        }while(next_permutation(ALL(per)));
        
        vector<Cost> ds=dijkstra(g,0);
        ll Mv=0;REP(code,ind)Mv=max(Mv,ds[code]);
        cout << Mv <<endl;
    }
};

int main(){
    cout <<fixed<<setprecision(20);
    cin.tie(0);
    ios::sync_with_stdio(false);
    Main().run();
    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 28700
final_rank: 8