zoukankan      html  css  js  c++  java
  • Codeforces Round #720 (Div. 2) D

    场上糊了一个小时都没糊出来(我甚至写了个假算法前半个多小时还没找到反例)

    因为题目最后要求我们得到的是一条链,删除的边的数量和加边的数量一样多,所以我们要让删除的边最少。又因为我们要得到的一条链肯定是由多条组合起来的,而原树是由多条链构成的,我们最少要删除链数-1条边,那么问题转换成了如何把树划分成最少的链数。

    考虑用贪心解决,在dfs到某个点u的时候,先处理u的子树,得到了一些仍然在和u连接的子节点,

    1. 如果子节点的数量为1,那么就继续把这个链往上传。

    2. 如果=2,就把这两个子节点合并成一条链,并把u和u的父亲断开

    3. 如果>2,就把某两个节点合并成一条链,剩下的拆成一条一条的链

    为什么这样是最优的呢,我们希望当前点u对u的父亲影响尽可能的小,所以在=2的时候,既然一定是把某两个点之间分离,变成两条不同的链,那把两个子节点合并成一条链,可以让u的父亲度数-1,让u的父亲有可能划分出更少的链,>2的时候也是同理。

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 10;
    vector < int > edge[N];
    vector < tuple <int, int, int, int> > ans;
    int md;
    int dfs(int x, int f) {
        int ch = 0, t = x;
        for (int u:edge[x]) {
            if (u == f)    continue;
            int v = dfs(u, x);
            if (!v)    continue; 
            ch++;
            if (ch == 1)    t = v;
            else if (ch == 2)    ans.emplace_back(x, f, v, md), md = t;
            else ans.emplace_back(u, x, u, md), md = v;    
        }    
        return (ch <= 1) ? t : 0; 
    }
    int main() {
        int T;
        scanf("%d", &T);
        while (T--) {
            int n;
            scanf("%d", &n);
            for (int i = 1; i < n; i++) {
                int x, y;
                scanf("%d%d", &x, &y);
                edge[x].push_back(y);
                edge[y].push_back(x);
            }
            md = 1;
            while (edge[md].size() != 1)    md++;
            dfs(md, 0);
            printf("%d
    ", ans.size());
            for (auto [a, b, c, d]:ans)
                printf("%d %d %d %d
    ", a, b, c, d);
            ans.clear();
            for (int i = 1; i <= n; i++)    edge[i].clear();
        }
        return 0;
    }
  • 相关阅读:
    Java线程
    腾讯2012.9.23校园招聘笔试题
    腾讯2011.10.15校园招聘笔试题
    腾讯2013年实习生笔试题目
    腾讯2012.4.25实习生招聘笔试题(2)
    腾讯2012.4.25实习生招聘笔试题
    优酷土豆2012.9.12校园招聘笔试题
    谷歌面试题:在半径为1的圆中随机选取一点
    Reservoir Sampling
    微软面试15道
  • 原文地址:https://www.cnblogs.com/cminus/p/14752504.html
Copyright © 2011-2022 走看看