首页 > 其他分享 >关于换根dp

关于换根dp

时间:2023-02-08 16:00:57浏览次数:44  
标签:int 2048 MX 关于 com 换根 dp

看到网上的方法多多少少比较复杂,所以决定写一下。

首先对于一道换根dp题应该是先要会不换根版本的。

然后可以按照欧拉序(括号序)换根。对于欧拉序中相邻的两个节点必有一条边把它们相连,所以换根的时候只需要从新统计 $1$ 个子树的信息。

觉得自己的语言表达能力太烂,还是上题目比较好。

 

[P3478 [POI2008] STA-Station](https://www.luogu.com.cn/problem/P3478)

求一个点的应该很好做,考虑 $f_u$ 表示点 $u$ 的子树中的答案,$sz_u$ 为 $u$的子树大小,有转移方程:
$$f_u=\sum_{v \in ch}(f_v+sz_v)$$

考虑如何进行换根。

![](https://cdn.luogu.com.cn/upload/image_hosting/fent371p.png?x-oss-process=image/resize,m_lfit,h_2048,w_2048)

假如把 $v$ 换成新的根,结果如下

![](https://cdn.luogu.com.cn/upload/image_hosting/gndhwtru.png?x-oss-process=image/resize,m_lfit,h_2048,w_2048)

可以发现,只有 $rt$ 与 $v$ 的信息改变了,所以将 $rt$ 减去 $v$ 的贡献,$v$
加上 $rt$ 的贡献即可。

code:

#include<vector>
#include<iostream>
using namespace std;

#define ll long long

const int MX=2e6+7;

vector<int > g[MX];
ll sz[MX],f[MX],ans=0;
int n,x,y,pos=0;

int read(){
    int x=0,ch=getchar();
    while(!(ch>=48&&ch<=57))ch=getchar();
    while(ch>=48&&ch<=57)x=x*10+ch-48,ch=getchar();
    return x;
}

void write(int x){
    if(x>9)write(x/10);
    putchar(x%10+48);
}

void dp(int x,int fa){
    sz[x]=f[x]=0;
    for(int i=0;i<g[x].size();i++){
        int to=g[x][i];
        if(to==fa)continue;
        dp(to,x);
        sz[x]+=sz[to];
        f[x]+=f[to]+sz[to];
    }
    sz[x]++;
}

void chg_rt(int rt,int newrt){
    f[rt]-=f[newrt]+sz[newrt];
    sz[rt]-=sz[newrt];
    f[newrt]+=f[rt]+sz[rt];
    sz[newrt]+=sz[rt];
    if(f[newrt]>ans){
        ans=f[newrt];
        pos=newrt;
    }
}

void dfs(int x,int fa){
    for(int i=0;i<g[x].size();i++){
        int to=g[x][i];
        if(to==fa)continue;
        chg_rt(x,to);
        dfs(to,x);
        chg_rt(to,x);
    }
}

int main(){
    ios::sync_with_stdio(false);
    n=read();
    for(int i=1;i<n;i++){
        x=read();
        y=read();
        g[x].push_back(y);
        g[y].push_back(x);
    }
    dp(1,1);
    dfs(1,1);
    write(pos);
    return 0;
}

 

[CF708C Centroids](https://codeforces.com/problemset/problem/708/C)

直接换根dp,不写了。

标签:int,2048,MX,关于,com,换根,dp
From: https://www.cnblogs.com/HJY2023/p/17102152.html

相关文章