【Luogu】P1131时态同步(树形DP)

  题目链接

  甚矣吾衰也!这么简单的DP我都不会了

  太恐怖了

  树形DP,从子树里选出时间最长的来,剩下的调到这个最长时间即可。

  

#include<cstdio>
#include<cctype>
#include<algorithm>
#include<cstring>

using std::max;

inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num*f;
}

struct Edge{
    int next,to,val;
}edge[3000020];
int head[1000200],num;
inline void add(int from,int to,int val){
    edge[++num]=(Edge){head[from],to,val};
    head[from]=num;
}

long long f[1020000];
void dfs(int x,int fa){
    for(int i=head[x];i;i=edge[i].next){
        int to=edge[i].to;
        if(to==fa)    continue;
        dfs(to,x);
        f[x]=max(f[x],f[to]+edge[i].val);
    }
}

long long calc(int x,int fa){
    long long ans=0;
    for(int i=head[x];i;i=edge[i].next){
        int to=edge[i].to;
        if(to==fa)    continue;
        ans+=calc(to,x);
        ans+=f[x]-f[to]-edge[i].val;
    }
    return ans;
}
        
int main(){
    int n=read(),S=read();
    for(int i=1;i<n;++i){
        int from=read(),to=read(),val=read();
        add(from,to,val);
        add(to,from,val);
    }
    dfs(S,S);
    printf("%lld",calc(S,S));
    return 0;
}

 

posted @ 2017-12-16 08:19  Konoset  阅读(163)  评论(0编辑  收藏  举报