题目链接 思路 可以利用random_shuffle()将打通宝藏屋的顺序随机出来,然后贪心求解即可。即 假如要打通第i个宝藏屋,那么从已打通的宝藏屋中选出打通道路花费最小的即可。 代码 #include<cstdio> #include<cstring> #include<algorithm> #define int long long #define ri register int #define min(a,b) a<b?a:b #define inf 0x7f7f7f7f using namespace std; int n,m,ans,an=inf,sum; int w[15][15]; int a[15],d[15]; int read(){ int x=0;char c=getchar(); while(c>'9'||c<'0') c=getchar(); while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar(); return x; } signed main(){ n=read(),m=read(); memset(w,127,sizeof w); while(m--) { int u=read(),v=read(),w1=read(); w[u][v]=w[v][u]=min(w[u][v],w1); } for(ri i=1;i<=n;++i) a[i]=i; for(ri t=1;t<=100000;++t)//多随机几遍,便于出正确答案 { random_shuffle(a+1,a+n+1); memset(d,0,sizeof d); d[a[1]]=1;sum=0;//记得初始化 for(ri i=2;i<=n;++i) { ans=inf; for(ri j=1;j<i;++j) { if(w[a[i]][a[j]]<inf) { int k=d[a[j]]*w[a[i]][a[j]]; if(k<ans) ans=k,d[a[i]]=d[a[j]]+1;//求出最小的花费,同时让深度加一 } } if(ans==inf)//如果无法打通,则说明此打通顺序无解,那么就不用再算了 { sum=inf; break; } else sum+=ans;//打通所需费用累加 } an=min(an,sum); } printf("%lld",an); return 0; } 我的状压DP题单 此题另一种解法:状压DP