#include<iostream>
#include<algorithm>
#include<cstdio>
#include<queue>
#define INF 100000
using namespace std;
int n;
int mp[100][100];
struct node {
int visp[22];
int st;
int st_p;
int ed;
int ed_p;
int k;
int sumv;
int lb;
bool operator <(const node &p )const {
return lb>p.lb;
}
};
priority_queue<node> q;
int low, up;
int inq[100];
int dfs(int u,int k,int l) {
if(k==n) return l+mp[u][1];
int minlen=INF , p;
for(int i=1; i<=n; i++) {
if(inq[i]==0&&minlen>mp[u][i]) {
minlen=mp[u][i];
p=i;
}
}
inq[p]=1;
return dfs(p,k+1,l+minlen);
}
int get_lb(node p) {
int ret=p.sumv*2;
int min1=INF,min2=INF;
for(int i=1; i<=n; i++) {
if(p.visp[i]==0&&min1>mp[i][p.st]) {
min1=mp[i][p.st];
}
}
ret+=min1;
for(int i=1; i<=n; i++) {
if(p.visp[i]==0&&min2>mp[p.ed][i]) {
min2=mp[p.ed][i];
}
}
ret+=min2;
for(int i=1; i<=n; i++) {
if(p.visp[i]==0) {
min1=min2=INF;
for(int j=1; j<=n; j++) {
if(min1>mp[i][j])
min1=mp[i][j];
}
for(int j=1; j<=n; j++) {
if(min2>mp[j][i])
min2=mp[j][i];
}
ret+=min1+min2;
}
}
return ret % 2 == 0 ? (ret / 2) : (ret / 2 + 1);
}
void get_up() {
inq[1]=1;
up=dfs(1,1,0);
}
void get_low() {
low=0;
for(int i=1; i<=n; i++) {
int min1=INF,min2=INF;
int tmpA[22];
for(int j=1; j<=n; j++) {
tmpA[j]=mp[i][j];
}
sort(tmpA+1,tmpA+1+n);
low+=tmpA[1];
}
}
int solve()
{
get_up();
get_low();
node star;
star.st=1;
star.ed=1;
star.k=1;
for(int i=1; i<=n; i++) star.visp[i]=0;
star.visp[1]=1;
star.sumv=0;
star.lb=low;
int ret=INF;
q.push(star);
while(!q.empty()) {
node tmp=q.top();
q.pop();
if(tmp.k==n-1) {
int p;
for(int i=1; i<=n; i++) {
if(tmp.visp[i]==0) {
p=i;
break;
}
}
int ans=tmp.sumv+mp[p][tmp.st] + mp[tmp.ed][p];
node judge = q.top();
if(ans <= judge.lb) {
ret=min(ans,ret);
break;
}
else {
up = min(up,ans);
ret=min(ret,ans);
continue;
}
}
node next;
for(int i=1; i<=n; i++) {
if(tmp.visp[i]==0) {
next.st=tmp.st;
next.sumv=tmp.sumv+mp[tmp.ed][i];
next.ed=i;
next.k=tmp.k+1;
for(int j=1; j<=n; j++) next.visp[j]=tmp.visp[j];
next.visp[i]=1;
next.lb=get_lb(next);
if(next.lb>up) continue;
q.push(next);
}
}
}
return ret;
}
int main()
{
freopen("tsp.txt", "r", stdin);
scanf("%d",&n);
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++)
{
if(i==j)
{
mp[i][j]=INF;
continue;
}
scanf("%d",&mp[i][j]);
}
}
printf("%d\n",solve());
return 0;
}
- 输入数据
- 运行结果