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
",ans);
return 0;
}
原文地址:https://www.cnblogs.com/lmjer/p/9412072.html