The following statements are equivalent:

a)......
b)......
c)......

For example, let A be an angle between 0 and 360 degrees, the following statements are equivalent:

a)A = 90 degrees;
b)A is a right angle;
c)sin(A) = 1.

Proving such a theorem is usually a difficult task, because you have to prove that for any two statements Si and Sj, Si concludes Sj and vise versa. Sometimes, proving Si concludes Sj directly is quite difficult so we may find a Sk and prove that Si concludes Sk and Sk concludes Sj. Now given the difficulty of proving every Si => Sj, you are to calculate the minimal total difficulty to prove that the given statements are equivalent.


Input

The input contains several cases. Each case begins with an integer n (2 <= n <= 6), the number of statements in this case, followed by n lines, each contains n integers.

The jth integer of the ith row represents the difficulty of proving Si => Sj. The ith integer of the ith row is always 0 as it's obvious that Si concludes Si. All the n * n integers are between 0 and 100, inclusively. Input is terminated by EOF.


Output

For each test case, output a line with the minimal difficulty for that case.


Sample Input

4
0 2 3 4
5 0 7 8
9 10 0 12
13 14 15 0


Sample Output

34




求一个完全图中,连那些边可以使得每个点出发都能到达全部的点,搜索加剪枝



#include<math.h>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N=1e5+10;
const double eps=1e-8;
int n,sz,b[50][8],ans,m;

struct point
{
int x,y,z;
bool operator<(const point&a)const
{
return z<a.z;
}
}a[N];

void dfs(int x,int sum)
{
if (sum>ans) return;
int cnt=0;
for (int i=0;i<n;i++)
{
cnt+=b[x][i]==m;
b[x+1][i]=b[x][i];
}
if (cnt==n)
{
ans=min(ans,sum);
return;
}

if (x==sz) return;
if (a[x].z==0)
{
for (int i=0;i<n;i++)
{
b[x+1][i]=b[x][i];
if (b[x][i]&(1<<a[x].x))
{
b[x+1][i]|=b[x][a[x].y];
}
}
dfs(x+1,sum);
}
else
{
for (int i=0;i<n;i++)
{
b[x+1][i]=b[x][i];
if (b[x][i]&(1<<a[x].x))
{
b[x+1][i]|=b[x][a[x].y];
}
}
dfs(x+1,sum+a[x].z);
for (int i=0;i<n;i++) b[x+1][i]=b[x][i];
dfs(x+1,sum);
}
}

int main()
{
while(~scanf("%d",&n))
{
m=(1<<n)-1;
sz = 0;
for (int i=0;i<n;i++)
{
for (int j=0;j<n;j++)
{
scanf("%d",&a[sz].z);
if (i==j) continue;
a[sz].x=i; a[sz++].y=j;
}
}
sort(a,a+sz);
for (int i=0;i<n;i++) b[0][i]=1<<i;
ans=0x7FFFFFFF;
dfs(0,0);
printf("%d\n",ans);
}
return 0;
}