1 //It is made by jump~
2 #include <iostream>
3 #include <cstdlib>
4 #include <cstring>
5 #include <cstdio>
6 #include <cmath>
7 #include <algorithm>
8 #include <ctime>
9 #include <vector>
10 #include <queue>
11 #include <map>
12 #include <set>
13 #ifdef WIN32
14 #define OT "%I64d"
15 #else
16 #define OT "%lld"
17 #endif
18 using namespace std;
19 typedef long long LL;
20 const int MAXN = 16;
21 const int MAXS = (1<<17);
22 int n;
23 int w[MAXN][MAXN];
24 int f[MAXN][MAXS];//f[i][j]表示到达i时状态为j的最小值
25
26 inline int getint()
27 {
28 int w=0,q=0;
29 char c=getchar();
30 while((c<‘0‘ || c>‘9‘) && c!=‘-‘) c=getchar();
31 if (c==‘-‘) q=1, c=getchar();
32 while (c>=‘0‘ && c<=‘9‘) w=w*10+c-‘0‘, c=getchar();
33 return q ? -w : w;
34 }
35
36 inline void solve(){
37 n=getint();
38 for(int i=0;i<=n;i++)
39 for(int j=0;j<=n;j++)
40 w[i][j]=getint();
41 for(int k=0;k<=n;k++)//预处理出最短路
42 for(int i=0;i<=n;i++)
43 for(int j=0;j<=n;j++)
44 w[i][j]=min(w[i][j],w[i][k]+w[k][j]);
45 int end=(1<<(n+1))-1;
46 memset(f,127/3,sizeof(f)); f[0][0]=0; f[0][1]=0;
47 for(int i=0;i<=end;i++)//此时状态为i,从from到now
48 for(int now=0;now<=n;now++)
49 for(int from=0;from<=n;from++) {
50 if(from==now) continue;
51 if( ( (1<<now) | i ) !=i) continue;//当前状态必须要经过i
52 f[now][i]=min(f[now][i],f[from][i-(1<<now)]+w[from][now]);//之前没到达过now
53 f[now][i]=min(f[now][i],f[from][i]+w[from][now]);//之前已经到达过now
54 }
55 printf("%d",f[0][end]);
56 }
57
58 int main()
59 {
60 solve();
61 return 0;
62 }