zoukankan      html  css  js  c++  java
  • 【ZBH选讲·树变环】

    【问题描述】
    你是能看到第三题的friends呢。
    ——aoao
    树是个好东西,删掉树一条边要1的代价,随便再加一条边有1的代价,求最小的代价把树变成环。
    【输入格式】
    第一行一个整数,代表树的点数。
    接下来−1行,每行两个数代表树的一条边。
    【输出格式】
    一行一个整数代表答案。
    【样例输入】
    4
    1 2
    2 3
    2 4
    【样例输出】
    3
    【数据规模与约定】
    对于30%的数据,1≤n≤10。
    对于60%的数据,1≤n≤1000。
    对于100%的数据,1≤n≤100000。

    题解:
             ①这是贪心还是DP还是构造还是Implentation……(我们争论了一会儿~)

             ②个人比较支持构造,最优的策略是:

                   思路:尝试先将树弄成一条链,最后加一条边变成环。

                   分类讨论: 

                       (1)当前点仅有一个子节点,那么什么都不做。

                       (2)当前点有1个以上的依旧相连子节点,那么此时最优的方案就是选取两个儿子

                          组成一条链,其余的儿子的边直接断掉,并且将这个点和父亲的连边断掉。

                  上述过程使用递归完成,并记录断边个数x。

                  由于最后整个树被拆成了x+1条链(或者点),然后在顺次连x+1条边就形成环。

                  因此最终答案就是x+x+1。

    #include<cstdio>
    #include<iostream>
    #define N 100001
    using namespace std;
    int front[N],nxt[N<<1],to[N<<1],tot;
    int ans;
    void add(int u,int v)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
    }
    int dfs(int x,int f)
    {
        int sum=0;
        for(int i=front[x];i;i=nxt[i])if(to[i]!=f) sum+=dfs(to[i],x);
        if(sum>=2)
        {
            if(x==1) ans+=sum-2;
            else ans+=sum-1;
            return 0;
        }
        return 1;
    }
    int main()
    {
        int n,u,v;scanf("%d",&n);
        for(int i=1;i<n;i++)scanf("%d%d",&u,&v),add(u,v);
        dfs(1,0);printf("%d",ans*2+1);
    }//Ztraveler

    点点滴滴往日的眷恋,寻寻觅觅又再回到我的身边,

    苦苦安顿抚平的回忆,骤然散落一如繁星的碎片……——————汪峰《回忆之前忘记之后》

  • 相关阅读:
    微信小程序实现课程表实例
    探索Java中的网络编程技术
    Java中的Spring MVC简介笔记
    我没有想赢,我只是不想输
    下次路过,人间再无我。
    从零基础入门MySQL数据库基础课
    vue.js-详解三大流行框架VUE_快速进阶前端大咖-Vue基础
    学习网站/实用工具,收藏的快搜网站,想找什么都有!!!
    【灵魂拷问】你真的懂得Mysql的管理和使用吗?
    【领会要领】web前端-轻量级框架应用(jQuery基础)
  • 原文地址:https://www.cnblogs.com/Damitu/p/7661767.html
Copyright © 2011-2022 走看看