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

    这题用换根DP非常好处理。

    先用(1)为根树形DP出第一个把(1)号点变成黑点所得到的贡献。然后发现若(x)的答案为(a[x])(v)(x)的子节点,那么(a[v]=a[x]+n-2 imes siz[v])(换根过程)。
    然后对每个点的答案去一个最大值就好了。

    代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    typedef long long LL;
    const int N=200009;
    int n,head[N],cnt,siz[N];
    LL fuck[N],ans,a[N];
    struct Edge
    {
    	int nxt,to;
    }g[N*2];
    
    void add(int from,int to)
    {
    	g[++cnt].nxt=head[from];
    	g[cnt].to=to;
    	head[from]=cnt;
    }
    
    void init()
    {
    	scanf("%d",&n);
    	int x,y;
    	for (int i=1;i<n;i++)
    		scanf("%d %d",&x,&y),add(x,y),add(y,x);
    }
    
    void dfs(int x,int fa)
    {
    	siz[x]=1;
    	for (int i=head[x];i;i=g[i].nxt)
    	{
    		int v=g[i].to;
    		if(v==fa)
    			continue;
    		dfs(v,x);
    		siz[x]+=siz[v];
    		fuck[x]+=fuck[v];
    	}
    	fuck[x]+=siz[x];
    }
    
    void DFS(int x,int fa)
    {
    	for (int i=head[x];i;i=g[i].nxt)
    	{
    		int v=g[i].to;
    		if(v==fa)
    			continue;
    		a[v]=a[x]-siz[v]+n-siz[v];
    		ans=max(ans,a[v]);
    		DFS(v,x);
    	}
    }
    
    void work()
    {
    	dfs(1,-1);
    	ans=a[1]=fuck[1];
    	DFS(1,-1);
    	printf("%lld
    ",ans);
    }
    
    int main()
    {
    	init();
    	work();
    	return 0;
    }
    
    由于博主比较菜,所以有很多东西待学习,大部分文章会持续更新,另外如果有出错或者不周之处,欢迎大家在评论中指出!
  • 相关阅读:
    exchangeNetwork
    VRP OS Management
    filleSystemBasises
    Study_way
    1.MySQL 安装
    7.进程池与线程池
    6.线程
    5.进程 -锁
    4.进程-1
    3.多线程TCP协议与加密方式
  • 原文地址:https://www.cnblogs.com/With-penguin/p/12735681.html
Copyright © 2011-2022 走看看