zoukankan      html  css  js  c++  java
  • CF1029E Tree with Small Distances

    CF1029E Tree with Small Distances

    洛谷传送门

    题目描述

    给定一颗有根树(根节点为 111)。要求往树中加入一些边使得从根节点到其他节点的距离至多是 222。 求加入边的最小数量。(边全部都是无向的)

    输入格式

    第一行一个整数 nnn,表示树中的节点个数。 接下来 n−1n−1n−1 行,每行两个整数 x,yx,yx,y,表示 x,yx,yx,y 之间有一条连边。

    输出格式

    一个整数,表示加入边的最小数量。


    题解:

    看到最优化想DP,没想出来。正解是贪心。

    肯定深度深的最不好伺候,先把深度深的搞定了之后,一层一层再逼近根节点这么搞,肯定是更优秀的。

    那怎么伺候深度深的呢?

    假设现在深度深的点为(x),如果直接连(x),肯定不划算的。我们如果连上他的父亲(f),那么肯定能使得更多的点符合条件。

    于是贪心原则就出来了。感性认知是对的。

    具体实现就是用堆来维护一个二元组,先处理深度打的节点,每次取出堆顶节点就打一圈标记。就解决了。

    代码:

    #include<cstdio>
    #include<queue>
    #include<algorithm>
    using namespace std;
    const int maxn=2e5+5;
    int n,ans;
    int tot,head[maxn],nxt[maxn<<1],to[maxn<<1];
    int deep[maxn],fa[maxn];
    bool v[maxn];
    priority_queue<pair<int,int> >q;
    void add(int x,int y)
    {
        to[++tot]=y;
        nxt[tot]=head[x];
        head[x]=tot;
    }
    void dfs(int x,int f)
    {
        deep[x]=deep[f]+1;
        fa[x]=f;
        if(deep[x]>2)
            q.push(make_pair(deep[x],x));
        for(int i=head[x];i;i=nxt[i])
        {
            int y=to[i];
            if(y==f)
                continue;
            dfs(y,x);
        }
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        deep[0]=-1;
        dfs(1,0);
        while(!q.empty())
        {
            int x=q.top().second;
            q.pop();
            if(v[x])
                continue;
            int f=fa[x];
            v[f]=1;
            for(int i=head[f];i;i=nxt[i])
            {
                int y=to[i];
                v[y]=1;
            }
            ans++;
        }
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    软件技术发展的几个阶段
    MOOONscheduler核心设计图(初稿)
    Write Read Writeln Readln console
    Win32Check对Windows操作 注销 重新启动 关闭计算机_Win32Check
    WM_nclButtonDblClk响应标题栏事件_message
    使用 “+”号实现多个字符串的连接
    TRichEdit_控制TRichEdit组件滚动
    取得字符串中指定的字符str[]
    undo RichEdit1
    使Memo 原有的右键功能失效 _OnContextPopup
  • 原文地址:https://www.cnblogs.com/fusiwei/p/14015240.html
Copyright © 2011-2022 走看看