码迷,mamicode.com
首页 > 其他好文 > 详细

[树形DP]Luogu P1131 [ZJOI2007]时态同步

时间:2019-06-05 20:09:00      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:show   记录   problem   ++   opened   mes   std   event   main   

https://www.luogu.org/problemnew/show/P1131

分析

我们设t[i]为以i为根的子树中需要最久达到的点所需的时间

那么我们容易用一次DFS预处理出来,再DFS记录深入到当前点已经加过k次,ans=Σ(t[rt]-t[u]-k),k=t[rt]-t[u]

 

技术图片
#include <iostream>
#include <cstdio>
using namespace std;
const int N=5e5+10;
struct Graph {
    int v,nx,w;
}g[2*N];
int cnt,list[N];
int n,rt;
int tme[N],mx;
long long ans;

void Add(int u,int v,int w) {
    g[++cnt]=(Graph){v,list[u],w};list[u]=cnt;
    g[++cnt]=(Graph){u,list[v],w};list[v]=cnt;
}

void DFS(int u,int fa) {
    for (int i=list[u];i;i=g[i].nx)
        if (g[i].v!=fa) {
            tme[g[i].v]=tme[u]+g[i].w;
            DFS(g[i].v,u);
        }
    for (int i=list[u];i;i=g[i].nx)
        if (g[i].v!=fa) tme[u]=max(tme[u],tme[g[i].v]);
}

void DFS(int u,int fa,int t) {
    for (int i=list[u];i;i=g[i].nx)
        if (g[i].v!=fa) {
            ans+=mx-tme[g[i].v]-t;
            DFS(g[i].v,u,mx-tme[g[i].v]);
        }
}

int main() {
    scanf("%d%d",&n,&rt);
    for (int i=1,u,v,w;i<n;i++) scanf("%d%d%d",&u,&v,&w),Add(u,v,w);
    DFS(rt,-1);
    for (int i=1;i<=n;i++) mx=max(mx,tme[i]);
    DFS(rt,-1,0);
    printf("%lld\n",ans);
}
View Code

 

[树形DP]Luogu P1131 [ZJOI2007]时态同步

标签:show   记录   problem   ++   opened   mes   std   event   main   

原文地址:https://www.cnblogs.com/mastervan/p/10981274.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!