• CF 1042 F. Leaf Sets


    F. Leaf Sets

    http://codeforces.com/contest/1042/problem/F

    题意:

      将所有的叶子节点分配到尽量少的集合,一个可行的集合中两两叶子节点的距离<=k。

    分析:

      可以证明,对于一个子树内的两个叶子节点,把它们分到同一个集合中一定比分到两个集合中好。

      所以一个子树内的叶子集合,能合并,尽量合并。

      从叶子节点dfs,往上推,当到达一个点时,求出这棵子树内所有的叶子集合到这个节点的距离。如果两个距离小于等于k,那么显然是可以合并的。合并后,只返回这棵子树内最小的距离。

      比赛时第33行是这样写的:if(t<k) c.push_back(t); 然后就在第4个测试点wa。。。

    代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<cctype>
     7 #include<set>
     8 #include<vector>
     9 #include<queue>
    10 #include<map>
    11 #define fi(s) freopen(s,"r",stdin);
    12 #define fo(s) freopen(s,"w",stdout);
    13 using namespace std;
    14 typedef long long LL;
    15 
    16 inline int read() {
    17     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    18     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    19 }
    20 
    21 const int N = 1000005;
    22 
    23 vector<int> T[N];
    24 int Ans = 0, n, k;
    25 int c[N], deg[N];
    26 
    27 int dfs(int u,int fa) {
    28     vector<int> c;
    29     for (int i=0; i<T[u].size(); ++i) {
    30         int v = T[u][i];
    31         if (v == fa) continue;
    32         int t = dfs(v, u);
    33         c.push_back(t);
    34     }
    35     int siz = c.size();
    36     if (!siz) return 1;
    37     
    38     sort(c.begin(), c.end());
    39     
    40     int ans = c[siz - 1];
    41     for (int i=1; i<siz; ++i) {
    42         if (c[i] + c[i - 1] <= k) Ans --;
    43         else {
    44             ans = min(ans, c[i - 1]);
    45             break; 
    46         }
    47     }
    48     return ans + 1;
    49 }
    50 
    51 int main() {
    52     n = read(), k = read();
    53     for (int i=1; i<n; ++i) {
    54         int u = read(), v = read();
    55         T[u].push_back(v), T[v].push_back(u);
    56         deg[u] ++, deg[v] ++;
    57     }
    58     int Root = 0;
    59     for (int i=1; i<=n; ++i) {
    60         if (deg[i] == 1) Ans ++;
    61         if (deg[i] > 1 && !Root) Root = i;
    62     }
    63     dfs(Root, 0);
    64     cout << Ans;
    65     return 0;
    66 }
  • 相关阅读:
    win10 uwp 读取保存WriteableBitmap 、BitmapImage
    win10 uwp 读取保存WriteableBitmap 、BitmapImage
    win10 uwp 按下等待按钮
    win10 uwp 按下等待按钮
    win10 uwp 右击选择 GridViewItem
    win10 uwp 右击选择 GridViewItem
    PHP array_column() 函数
    PHP array_chunk() 函数
    PHP array_change_key_case() 函数
    PHP array() 函数
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9664830.html
Copyright © 2020-2023  润新知