Source of title: http://acm.hdu.edu.cn/showproblem.php?pid=5418

At first I thought it was TSP, but later I found that there was a difference between the two.

Traveling salesman problem: the shortest path a person needs to go through n other points once from one point and return to the origin (no more than one time, no less)

### Translation:

Topic: The shortest path needed to start at one point and go to other points at least once

## Train of thought:

Actually, the feeling of this question is not much different from that of TSP.

Firstly, we need to deal with the distance between points, and get the shortest path dis[i][j] between each point.

(Here I use the most convenient floyed, you can use more advanced SPFA or something.)

Then, like the traveling salesman problem, we define the shortest path when dp[i][j] denotes that the last endpoint of state I is point J.

There is a transfer equation, such as right dp[i| (1<<j-1)][j]=min (dp[i| (1<<j-1)][j], dp[i][k]+dis[k][j]), which is exactly the same as TSP.

If it's really over, I probably won't post this blog.

According to the above idea, the next step in the cycle of finding the minimum value is as follows: ans=min(ans,dp[num-1][i]+dis[i][1]);

The first half of the formula is correct, but the last dis [i] [1] is wrong

Think about it carefully. Is dis [i] [1] really problematic? I haven't figured it out yet. But the positive solution is to add an array d [i] to save the shortest path of the path with point I as the endpoint, and replace it with D [i] to AC s. I'll think about it tomorrow.

## Code:

#include<iostream> #include<algorithm> #include<string> #include<vector> #include<set> #include<map> #include<queue> #include<stack> #include<deque> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int maxn=20; const int sz=1<<16; const int inf=2e9; const int mod=1e9+7; const double pi=acos(-1); typedef long long LL; int n,m; int dis[maxn][maxn]; int dp[sz][17]; int d[17]; template<class T> inline void read(T &x) { char c;x=1; while((c=getchar())<'0'||c>'9') if(c=='-') x=-1; T res=c-'0'; while((c=getchar())>='0'&&c<='9') res=res*10+c-'0'; x*=res; } int main() { int t; read(t); while(t--){ read(n); read(m); memset(dis,127/3,sizeof dis); while(m--){ int a,b,c; read(a); read(b); read(c); if(dis[a][b]>c) dis[a][b]=dis[b][a]=c; } for(int k=1;k<=n;k++){ for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(i!=j&&j!=k&&k!=i&&dis[i][j]>dis[i][k]+dis[k][j]) dis[i][j]=dis[i][k]+dis[k][j]; } } } int num=1<<n; memset(dp,127/3,sizeof dp); memset(d,127/3,sizeof d); dp[1][1]=0; for(int i=0;i<num;i++){ for(int j=1;j<=n;j++){ if(!(i&(1<<j-1))){ for(int k=1;k<=n;k++){ if(i&(1<<k-1)) dp[i|(1<<j-1)][j]=min(dp[i|(1<<j-1)][j],dp[i][k]+dis[k][j]); d[j]=min(dp[i|(1<<j-1)][j],d[j]); } } } } int ans=inf; for(int i=1;i<=n;i++) ans=min(ans,dp[num-1][i]+d[i]); cout<<ans<<endl; } return 0; }