P1131 [ZJOI2007] 时态同步

P1131 [ZJOI2007] 时态同步 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这更多是一个思维题

 

 

 看到上面这副图,我们的想法是先让 1→2和1→3拉伸到1→4的深度,再让5→1的叶子拉伸到5→6

我们便令dis[x]为x子树中最深的深度,对x节点进行操作

我们已经在v子树的操作中让v子树的每个叶子都是深度都是等深的

令dp[x]为让x子树中每个叶子等深所需的操作次数,当然这题不是树形dp,但用到树形dp的思想

接下来便是让x子树中每个叶子等深,所以我们先要找到最深的叶子max(dis[v]+val[x][v]),令他们的距离为dis[x];

然后让v子树拉伸,拉伸的长度为:dis[x]-(dis[v]+val[x][v])。

统计dp[x]+=dp[v]+(dis[x]-(dis[v]+val[x][v]);

Code:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pb push_back   
#define popb pop_back  
#define fi first
#define se second
const int N=5e5+10;
//const int M=;
//const int inf=0x3f3f3f3f;     
//const ll INF=0x3ffffffffffff;
int T,n,root;
ll dp[N],dis[N];
vector<int> g[N],val[N]; 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
void dfs(int x,int fa)
{
    for(int i=0;i<g[x].size();i++)
    {
        int v=g[x][i];
        if(v==fa) continue;
        dfs(v,x);
        dis[x]=max(dis[x],dis[v]+val[x][i]);
    }
    for(int i=0;i<g[x].size();i++)
    {
        int v=g[x][i];
        if(v==fa) continue;
        dp[x]+=(dp[v]+dis[x]-dis[v]-val[x][i]);
    }
}
int main()
{
//    freopen("","r",stdin);
//    freopen("","w",stdout);
    n=read();root=read();
    for(int i=1;i<n;i++)
    {
        int u=read(),v=read(),t=read();
        g[u].pb(v);val[u].pb(t);
        g[v].pb(u);val[v].pb(t);
    }
    dfs(root,0);
    printf("%lld",dp[root]);
    return 0;
}

 

posted @ 2023-03-12 20:13  QAQ啥也不会  阅读(24)  评论(0编辑  收藏  举报