• CF 600 E Lomsat gelral (DSU on tree)


    题意:给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和

    思路:dsu on tree 。暴力求轻边的答案,再加上重边的答案。

    #include<bits/stdc++.h>
    #define LL long long 
    using namespace std;
    const int MAXN = 1e5 + 10;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    int N, col[MAXN], son[MAXN], siz[MAXN], cnt[MAXN], Mx, Son;
    LL sum = 0, ans[MAXN];
    vector<int> v[MAXN];
    void dfs(int x,int fa)
    {
    	siz[x]=1;
    	for(int i=0;i<v[x].size();i++){
    		int to=v[x][i];
    		if(to==fa) continue;
    		dfs(to,x);
    		siz[x]+=siz[to];
    		if(siz[to]>siz[son[x]]) son[x]=to;
    	}	
    } 
    void add(int x,int fa,int val)
    {
    	cnt[col[x]]+=val;
    	if(cnt[col[x]]> Mx) Mx=cnt[col[x]],sum=col[x];
    	else if(cnt[col[x]] == Mx) sum+=(LL)col[x];
    	for(int i=0;i<v[x].size();i++){
    		int to=v[x][i];
    		if(to==fa || to ==Son) continue;
    		add(to,x,val);
    	}
    }
    void dfs2(int x,int fa,int opt){
    	for(int i=0;i<v[x].size();i++){
    		int to=v[x][i];
    		if(to==fa) continue;
    		if(to!=son[x]) dfs2(to,x,0);
    	}
    	if(son[x]) dfs2(son[x],x,1),Son=son[x];
    	add(x,fa,1);Son=0;
    	ans[x]=sum;
    	if(!opt) add(x,fa,-1),sum=0,Mx=0;
    }
    int main()
    {
    	N=read();
    	for(int i=1;i<=N;i++) col[i]=read();
    	for(int i=1;i<=N-1;i++){
    		int x=read(),y=read();
    		v[x].push_back(y);
    		v[y].push_back(x);
    	}
    	dfs(1,0);
    	dfs2(1,0,0);
    	for(int i=1;i<=N;i++) printf("%lld ",ans[i]);
    	
    }
    

      

  • 相关阅读:
    Swift
    Swift
    Swift
    Swift
    Swift
    Swift
    Swift
    Swift
    Swift
    算法の序列
  • 原文地址:https://www.cnblogs.com/The-Pines-of-Star/p/12288482.html
Copyright © 2020-2023  润新知