参照消防局那题和这题的题解想出的一个缝合怪解法 不知道哪里出问题
查看原帖
参照消防局那题和这题的题解想出的一个缝合怪解法 不知道哪里出问题
314588
cybercsc楼主2020/9/4 12:57

大佬们如果有时间的话可以帮忙看看 漏洞百出的想法 (我承认我有点执拗 但是我就是想把类似的题凑一起比较QAQ)

#include <bits/stdc++.h>
#define maxn 500000+10
#define maxm 20+5
using namespace std;
int e[2*maxn],ne[2*maxn],h[maxn],idx=0,dp[2][maxn][maxm],w[maxn],b[maxn],d;
int sum[2][maxm];
inline void add(int fa,int son){
    e[idx]=son;
    ne[idx]=h[fa];
    h[fa]=idx;
    idx++;
}
inline void dfs(int fa,int pa){
    if(b[fa]){dp[1][fa][0]=dp[0][fa][0]=w[fa];}//这个地方着实没法理解
    //其他所有转移都看懂了 唯独初始状态
    //思考了整整一天 只能归结于玄学
    for(int i=1;i<=d;i++)dp[1][fa][i]=w[fa];//0x3f3f3f3f;
    //dp[1][fa][d]=w[fa];
    for(int i=h[fa];i!=-1;i=ne[i]){
        int v=e[i];
        if(v==pa)continue;
        dfs(v,fa);
        for(int k=0;k<=d;k++){sum[0][k]+=dp[0][v][k];}
    }
    for(int i=h[fa];i!=-1;i=ne[i]){
        int v=e[i];
        if(v==pa)continue;
        for(int i=0;i<d;i++)dp[1][fa][i]=min(dp[1][fa][i],dp[1][v][i+1]+sum[0][i]-dp[0][v][i]);
        dp[1][fa][d]+=dp[0][v][d];
        dp[0][fa][0]=dp[1][fa][0];
    }
    for(int i=1;i<=d;i++){dp[0][fa][i]=min(sum[0][i-1],dp[0][fa][i-1]);}
    for(int i=d-1;i>=0;i--)dp[1][fa][i]=min(dp[1][fa][i+1],dp[1][fa][i]);

}

int main(){
    int n,m,tp,fa,son;
    cin>>n>>d;memset(h,-1,sizeof(h));
    for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    cin>>m;
    for(int i=1;i<=m;i++){scanf("%d",&tp);b[tp]=1;}
    for(int i=1;i<=n-1;i++){scanf("%d %d",&fa,&son);add(fa,son);add(son,fa);}
    dfs(1,0);
    cout<<dp[1][1][0];
    return 0;
}

2020/9/4 12:57
加载中...