noip2017(宝藏)
直接爆搜+状压dp即可
设dp[i] 表示为状态为i时的最大值
则dp[i]=max{dp[x]+deep[i]*w[i]}
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int nil=0x7f7f7f7f; int tu[20][20],d[20]; ll dp[1<<12]; int n,m; int g[20][20]; void dfs(int x){ for (int i=1;i<=n;i++){ if((1<<(i-1))&x){ for (int j=1;j<=n;j++){ if(!(1<<(j-1)&x) && g[i][j]){ if(dp[1<<(j-1)|x]>dp[x]+d[i]*tu[i][j]){ int temp=d[j]; d[j]=d[i]+1; dp[1<<(j-1)|x]=dp[x]+d[i]*tu[i][j]; dfs(1<<(j-1)|x); d[j]=temp; } } } } } } int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++){ for (int j=1;j<=n;j++){ tu[i][j]=nil; } } int u,v,w; for (int i=1;i<=m;i++){ scanf("%d%d%d",&u,&v,&w); tu[u][v]=tu[v][u]=min(tu[u][v],w); g[u][v]=g[v][u]=1; } ll ans=nil; for (int i=1;i<=12;i++){ for (int j=0;j< 1<<n ;j++) dp[j]=nil; dp[1<<(i-1)]=0; d[i]=1; dfs(1<<(i-1)); ans=min(ans,dp[(1<<n)-1]); } printf("%lld\n",ans); return 0; }