题目大意:
题解:
这题不难发现,f[i]表示选了的点的状态为i,用的最小代价,dis[i]表示起点到i经过的宝藏数。
然后转移的话,不知道从何做起,
后发现可以枚举能作为起点的N个点,然后果断用dfs去更新
代码:
#include<cstdio>
#define INF 1234567890
int n,m,rp,a[20][20],f[10000],dis[20];
int min(int aa , int bb)
{
if (aa>bb) return bb;
return aa;
}
void dfs(int dep)
{
for (int i=1; i<=n; i++)
if ( (1<<(i-1)) & dep )
{
for (int j=1; j<=n; j++)
if ( !( (1<<(j-1)) & dep ) && a[i][j]!=INF )
{
if (f[dep+(1<<(j-1))]>f[dep]+dis[i]*a[i][j])
{
rp=dis[j];
dis[j]=dis[i]+1;
f[dep+(1<<(j-1))]=f[dep]+dis[i]*a[i][j];
dfs(dep+(1<<(j-1)));
dis[j]=rp;
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++) a[i][j]=INF;
int u,v,w,ans=INF;
for (int i=1; i<=m; i++)
{
scanf("%d%d%d",&u,&v,&w);
a[u][v]=min(a[u][v],w);
a[v][u]=min(a[v][u],w);
}
for (int i=1; i<=n; i++) dis[i]=INF;
for (int k=1; k<=n; k++)
{
for (int i=1; i<=(1<<n)-1; i++) f[i]=INF;
dis[k]=1;
f[1<<(k-1)]=0;
dfs(1<<(k-1));
ans=min(ans,f[(1<<n)-1]);
}
printf("%d",ans);
return 0;
}