zoukankan      html  css  js  c++  java
  • Lomsat gelral cf-600e

    http://codeforces.com/contest/600/problem/E

    暴力启发式合并就行了

    提示:set的swap的复杂度是常数,这方面可以放心

    我先打了一个很naive的算法

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<set>
     5 #include<map>
     6 using namespace std;
     7 typedef long long LL;
     8 typedef pair<LL,LL> P;
     9 typedef set<P> s;
    10 //P(颜色出现次数,颜色编号)
    11 typedef map<LL,LL> m;
    12 //颜色编号->颜色出现次数
    13 typedef pair<s,m> P2;
    14 LL n,anss[100100],c[100100];
    15 vector<LL> e[100100];
    16 P2 dfs(LL u,LL fa)
    17 {
    18     P2 t,ans;
    19     ans.first.emplace(1,c[u]);
    20     ans.second[c[u]]=1;
    21     for(auto v:e[u])
    22         if(v!=fa)
    23         {
    24             t=dfs(v,u);
    25             if(t.second.size()>ans.second.size())    swap(t,ans);
    26             for(auto it:t.second)
    27             {
    28                 ans.first.erase(P(ans.second[it.first],it.first));
    29                 ans.second[it.first]+=it.second;
    30                 ans.first.emplace(ans.second[it.first],it.first);
    31             }
    32         }
    33     int maxsz=ans.first.rbegin()->first;
    34     for(auto it=ans.first.rbegin();it!=ans.first.rend()&&it->first==maxsz;it++)    anss[u]+=it->second;
    35     return ans;
    36 }
    37 int main()
    38 {
    39     LL i,x,y;
    40     scanf("%lld",&n);
    41     for(i=1;i<=n;i++)    scanf("%lld",&c[i]);
    42     for(i=1;i<n;i++)
    43     {
    44         scanf("%lld%lld",&x,&y);
    45         e[x].push_back(y);e[y].push_back(x);
    46     }
    47     dfs(1,0);
    48     for(i=1;i<=n;i++)    printf("%lld ",anss[i]);
    49     return 0;
    50 }
    View Code

    毫不意外的被卡掉了~看第34行,怎么看都不对嘛

    有两种解决方法:

    第一种:每一个节点dfs的时候额外返回一个值,记录当前子树的答案。

    第二种:将set换成另一个map<int,int>,记录颜色出现次数->编号之和

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<map>
     5 using namespace std;
     6 typedef long long LL;
     7 typedef map<LL,LL> m;
     8 //颜色出现次数->编号之和
     9 //颜色编号->颜色出现次数
    10 typedef pair<m,m> P2;
    11 LL n,anss[100100],c[100100];
    12 vector<LL> e[100100];
    13 P2 dfs(LL u,LL fa)
    14 {
    15     P2 t,ans;
    16     ans.first[1]=c[u];
    17     ans.second[c[u]]=1;
    18     for(auto v:e[u])
    19         if(v!=fa)
    20         {
    21             t=dfs(v,u);
    22             if(t.second.size()>ans.second.size())    swap(t,ans);
    23             for(auto it:t.second)
    24             {
    25                 ans.first[ans.second[it.first]]-=it.first;
    26                 ans.second[it.first]+=it.second;
    27                 ans.first[ans.second[it.first]]+=it.first;
    28             }
    29         }
    30     anss[u]=ans.first.rbegin()->second;
    31     return ans;
    32 }
    33 int main()
    34 {
    35     LL i,x,y;
    36     scanf("%lld",&n);
    37     for(i=1;i<=n;i++)    scanf("%lld",&c[i]);
    38     for(i=1;i<n;i++)
    39     {
    40         scanf("%lld%lld",&x,&y);
    41         e[x].push_back(y);e[y].push_back(x);
    42     }
    43     dfs(1,0);
    44     for(i=1;i<=n;i++)    printf("%lld ",anss[i]);
    45     return 0;
    46 }

    也可以将每个节点dfs返回的值改成全局变量(似乎可以避免一些玄学的常数问题)

  • 相关阅读:
    POJ
    POJ
    HDU——1027Ignatius and the Princess II(next_permutation函数)
    HDU——1106排序(istringstream的使用、STLvector练习)
    HDU——2054A==B?
    HDU——2087剪花布条
    HDU——2064汉诺塔III
    HDU——2068RPG的错排(错排公式)
    HDU——1789Doing Homework again(贪心)
    HDU——2067小兔的棋盘(卡特兰数&递推DP)
  • 原文地址:https://www.cnblogs.com/hehe54321/p/cf-600e.html
Copyright © 2011-2022 走看看