P3478 [POI2008] STA-Station

原题链接

WARNING!!! 使用map代替数组不再可靠,因为map的插入查找修改复杂度均为 O(logn) ,即使unorder_map也不行!!!

题解

我们发现,当一个节点的深度之和已知时(这里认为是根节点),其相邻节点的深度之和也可通过某种方程转移而得,有人称这种方法为换根DP

具体的,将树拆开成图(求深度之和的时候是树),已知节点 A 向右边相邻一条节点 B 移动,等价于 A 左边的节点(包括 A )到 A 之后再往右走一步,左边少走一步
怎么表示这个左边右边的节点呢?

再回到树的视角,等价于 f[B]=f[A]size[B]+nsize[B] 其中 size[B] 代表 B 的子树大小

因为树中父节点与子节点的大头针插入式的边才有这样的感觉??

code

#define ll long long
#include<bits/stdc++.h>
using namespace std;
vector<ll> G[1000005];
ll sizes[1000005],depth[1000005],dp[1000005];
ll n;

void dfs1(ll now,ll fa)
{
    sizes[now]=1;
    depth[now]=depth[fa]+1;
    for(auto next:G[now])
    {
        if(next==fa) continue;
        dfs1(next,now);
        sizes[now]+=sizes[next];
    }
}

void dfs2(ll now,ll fa)
{
    for(auto next:G[now])
    {
        if(next==fa)continue;
        dp[next]=dp[now]-sizes[next]+(n-sizes[next]);
        dfs2(next,now);
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(ll i=1;i<n;i++)
    {
        ll x,y;
        cin>>x>>y;
        G[x].emplace_back(y);
        G[y].emplace_back(x);
    }

    dfs1(1,0);
    for(ll i=1;i<=n;i++) dp[1]+=depth[i];
    dfs2(1,0);

    ll ans=0,id;
    for(ll i=1;i<=n;i++)
    {
        if(dp[i]>ans)
        {
            ans=dp[i];
            id=i;
        }
    }

    cout<<id;
    return 0;
}
posted @   纯粹的  阅读(9)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示