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返回的值改成全局变量(似乎可以避免一些玄学的常数问题)

  • 相关阅读:
    yolo_to_onnx ValueError: need more tan 1 value to unpack
    yolo_to_onnx killed
    C++ 实现二维矩阵的加减乘等运算
    Leetcode 1013. Partition Array Into Three Parts With Equal Sum
    Leetcode 1014. Best Sightseeing Pair
    Leetcode 121. Best Time to Buy and Sell Stock
    Leetcode 219. Contains Duplicate II
    Leetcode 890. Find and Replace Pattern
    Leetcode 965. Univalued Binary Tree
    Leetcode 700. Search in a Binary Search Tree
  • 原文地址:https://www.cnblogs.com/hehe54321/p/cf-600e.html
Copyright © 2011-2022 走看看