题意:
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/db31f3c6f4feddc21ee94d72b702168a.png)
解法:
先预处理出任意两点之间的路径,
因为每个点可以经过超过一次,因此floyd一下处理出最短路.
然后问题就是普通的tsp问题了,用状压dp解决.
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int x[18],y[18],z[18];
int d[1<<17][18];
int g[18][18];
int n;
int cal(int i,int j){
return abs(x[j]-x[i])+abs(y[j]-y[i])+max(0LL,z[j]-z[i]);
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>n;
for(int i=0;i<n;i++){
cin>>x[i]>>y[i]>>z[i];
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
g[i][j]=cal(i,j);
}
}
for(int k=0;k<n;k++){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
}
}
for(int i=0;i<(1<<n);i++){
for(int j=0;j<n;j++){
d[i][j]=1e18;
}
}
d[(1<<0)][0]=0;
for(int i=0;i<(1<<n);i++){
for(int j=0;j<n;j++){
if(d[i][j]==1e18)continue;
for(int k=0;k<n;k++){
if(i>>k&1)continue;
d[i|(1<<k)][k]=min(d[i|(1<<k)][k],d[i][j]+g[j][k]);
}
}
}
int ans=1e18;
for(int i=0;i<n;i++){
ans=min(ans,d[(1<<n)-1][i]+g[i][0]);
}
cout<<ans<<endl;
return 0;
}