正解:状压$dp$
解题报告:
$8102$年的时候就想搞这题了,,,$9102$了$gql$终于开始做这题了$kk$
发现有意义的状态只有当前选的点集和深度,所以设$f_{i,j}$表示当前深度为$i$,选了的点集状态为$j$.
然后转移就$f_{i,S}=min(f_{i-1,S_0}+cost)$,其中$S_0$为$S$的子集,$cost$为$S\ xor\ S_0$中的所有点和$S_0$的连边乘以$i$.
正确性显然?然后说下就,这里是并没有限制一定是和第$i-1$层的点连边的嘛,这样看起来有锅但其实是没问题的$QwQ$.就因为这样显然只会导致更劣,但这个情况一定会在其他转移中被正确转移到,所以是没影响的(,,,我$484$讲得还是不太清楚,,,$umm$如果没懂直接在评论区问趴$kk$.
然后就做完了$QwQQQQQ.$
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define int long long
#define gc getchar()
#define ri register int
#define rb register bool
#define rc register char
#define lowbit(x) (x&(-x))
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i) const int N=,inf=1e9;
int n,m,dis[N][N],f[N][<<N],S,as,lg[<<N]; il int read()
{
ri x=;rb y=;rc ch=gc;
while(ch!='-' && (ch<'' || ch>''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il int cal(ri x,ri y)
{
ri ret=;
while(x)
{
ri nw=lg[lowbit(x)],tmp=y,t=inf;x-=lowbit(x);
while(tmp)t=min(t,dis[nw][lg[lowbit(tmp)]]),tmp-=lowbit(tmp);;ret+=t;
}
return ret;
} signed main()
{
freopen("3959.in","r",stdin);freopen("3959.out","w",stdout);
n=read();m=read();memset(dis,,sizeof(dis));
rp(i,,m){ri x=read()-,y=read()-,z=read();dis[x][y]=dis[y][x]=min(dis[x][y],z);}
memset(f,,sizeof(f));rp(i,,n-)f[][<<i]=,lg[<<i]=i;S=(<<n)-;
rp(i,,S){ri j=(i-)&i;while(j){ri k=i^j,d=cal(k,j);rp(p,,n-)f[p][i]=min(f[p][i],f[p-][j]+d*p);j=(j-)&i;}}
as=f[][];rp(i,,n-)as=min(as,f[i][S]);printf("%lld\n",as);
return ;
}