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;
}