zoukankan      html  css  js  c++  java
  • 【CF1187E】Tree Painting

    题目大意:给定一棵 N 个点的树,初始全是白点。要求你做 N 步操作,每一次选定一个与一个黑点相隔一条边的白点,将它染成黑点,然后获得该白点被染色前所在的白色联通块大小的权值。第一次操作可以任意选点,求可获得的最大权值。

    题解:对于答案仅由起始点决定的 dp 采用换根法。
    发现对于两个相邻的染了黑色的点来说,这两个点染色的先后顺序会对答案产生影响,但是不会对其他点产生影响。同时,可以发现该问题一旦选定了初始点,无论怎样进行染色,答案均相同。因此,考虑采用换根法,需要计算出相邻两个点先后顺序对答案的影响,根据第一个性质,可知仅需要计算第一次两个点对答案的影响即可。画图可知,相邻两点对答案贡献的差值为 (n-2*sz[v])

    代码如下

    #include <bits/stdc++.h>
    #define pb push_back
    using namespace std;
    const int maxn=2e5+10;
    typedef long long LL;
    
    int n,sz[maxn];
    vector<int> G[maxn];
    LL f[maxn],ans;
    
    void dfs1(int u,int fa){
    	sz[u]=1;
    	for(auto v:G[u]){
    		if(v==fa)continue;
    		dfs1(v,u);
    		sz[u]+=sz[v];
    	}
    	ans+=sz[u];
    }
    void dfs2(int u,int fa){
    	ans=max(ans,f[u]);
    	for(auto v:G[u]){
    		if(v==fa)continue;
    		f[v]=f[u]+n-2*sz[v];
    		dfs2(v,u);
    	}	
    }
    void read_and_parse(){
    	scanf("%d",&n);
    	for(int i=1;i<n;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		G[x].pb(y),G[y].pb(x);
    	}
    }
    void solve(){
    	dfs1(1,0);
    	f[1]=ans;
    	dfs2(1,0);
    	printf("%lld
    ",ans);
    }
    int main(){
    	read_and_parse();
    	solve();
    	return 0;
    }
    
  • 相关阅读:
    rsync+inotify-tools实时备份脚本
    rsync+inotify实现实时同步
    linux 上安装部署python
    rsync全网备份low方法
    rsync 参数说明及使用参数笔记好文摘抄
    rsync 参数说明及使用参数笔记
    js DOM
    导出Excel
    Linux(CentOS 8)安装docker
    Win10安装虚拟机
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/11182018.html
Copyright © 2011-2022 走看看