Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], skipTags: ["script","noscript","style","textarea","code"], processEscapes: true }});

問題文

$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以下でソートできることを示すことができる。

Solution in C++ (judge verdict: Accepted)

#include<stdio.h>
#include<algorithm>
#include<map>
#include<queue>
using namespace std;
int c[8][8];
struct wolf{
	int v[8];
};
inline bool operator<(const wolf&a,const wolf&b){
	for(int i=0;i<8;i++)if(a.v[i]!=b.v[i])return a.v[i]<b.v[i];
	return false;
}
map<wolf,int>ijk;
priority_queue<pair<int,wolf> > Q;
int main(){
	int a;
	scanf("%d",&a);
	for(int i=0;i<a;i++)
		for(int j=0;j<a;j++)
			scanf("%d",&c[i][j]);
	wolf s;
	for(int i=0;i<a;i++)s.v[i]=i;
	Q.push(make_pair(0,s));
	int ret=0;
	while(Q.size()){
		int cost=-Q.top().first;
		wolf now=Q.top().second;
		Q.pop();
		if(ijk.count(now))continue;
		ijk[now]=cost;
		ret=max(ret,cost);
		for(int i=0;i<a;i++)
			for(int j=i+1;j<a;j++){
				int w=now.v[i];
				now.v[i]=now.v[j];
				now.v[j]=w;
				if(!ijk.count(now)){
					Q.push(make_pair(-cost-c[i][j],now));
				}
				w=now.v[i];
				now.v[i]=now.v[j];
				now.v[j]=w;
			}
	}
	printf("%d\n",ret);
	
}