CF600E Lomsat gelral

题目链接:https://www.luogu.com.cn/problem/CF600E

思路: 先处理出那些点是重儿子  然后对于每一个结点 先处理完轻儿子 再暴力清除掉

然后再处理重儿子 处理之后不用清除,回到根结点 再让处理根节点,让根节点带上重儿子的信息再跑一遍轻儿子的信息得到答案

暴力的话 每个点跑2n次 是n^2 只跑轻儿子的话 则时间复杂度 o(nlogn)

CF600E Lomsat gelral
  1 #include<bits/stdc++.h>
  2 #define ll long long
  3 #define pb push_back
  4 using namespace std;
  5 const int maxn=1e5+10;
  6 const int mod=1e9+7;
  7 vector<int>E[maxn];
  8 int n,son[maxn],cnt[maxn];
  9 int c[maxn],num[maxn],vis[maxn];
 10 ll ans[maxn];
 11 
 12 void get(int u,int fa)
 13 {
 14     cnt[u]=1;
 15     int p=0,max1=0;
 16     for(auto &v:E[u])
 17     {
 18         if(v==fa)
 19             continue;
 20         get(v,u);
 21         if(cnt[v]>max1)
 22         {
 23             max1=cnt[v];
 24             p=v;
 25         }
 26         cnt[u]+=cnt[v];
 27     }
 28     vis[p]=1;
 29 }
 30 ll sum=0,max1=0;
 31 
 32 void init(int u,int fa)
 33 {
 34     num[c[u]]--;
 35     for(auto &v:E[u])
 36     {
 37         if(v==fa)
 38             continue;
 39         init(v,u);
 40     }
 41 }
 42 
 43 void solve(int u,int fa,int p)
 44 {
 45     num[c[u]]++;
 46     if(num[c[u]]>max1)
 47     {
 48         max1=num[c[u]];
 49         sum=c[u];
 50     }
 51     else if(num[c[u]]==max1)
 52     {
 53         sum+=c[u];
 54     }
 55     for(auto &v:E[u])
 56     {
 57         if(v==fa||v==p)//不能把重儿子也跑了
 58             continue;
 59         solve(v,u,p);
 60     }
 61 }
 62 
 63 void dfs(int u,int fa)
 64 {
 65     int p=0;
 66     for(auto &v:E[u])
 67     {
 68         if(v==fa)
 69             continue;
 70         if(!vis[v])
 71         {
 72             dfs(v,u);
 73             init(v,u);
 74             max1=0,sum=0;
 75         }
 76         else
 77             p=v;
 78     }
 79     if(p) dfs(p,u);
 80     solve(u,fa,p);
 81     ans[u]=sum;
 82 
 83 }
 84 
 85 
 86 int main()
 87 {
 88     ios::sync_with_stdio(0);
 89     cin.tie(0);
 90     cin>>n;
 91     for(int i=1;i<=n;i++)
 92     {
 93         cin>>c[i];
 94     }
 95     for(int i=1;i<n;i++)
 96     {
 97         int x,y;
 98         cin>>x>>y;
 99         E[x].pb(y);
100         E[y].pb(x);
101     }
102     get(1,0);
103     dfs(1,0);
104     for(int i=1;i<=n;i++)
105     {
106         if(i!=1)
107             cout<<" ";
108         cout<<ans[i];
109     }
110     cout<<'\n';
111 
112 
113 }
View Code

 

上一篇:「题解」 [CF600E] Lomsat gelral


下一篇:CF1063F-String Journey【SAM,线段树】