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

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

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

  • 相关阅读:
    [leetcode]43. Multiply Strings
    [leetcode]387. First Unique Character in a String
    Penetration Test
    Penetration Test
    Penetration Test
    Penetration Test
    Penetration Test
    Penetration Test
    Penetration Test
    Penetration Test
  • 原文地址:https://www.cnblogs.com/Damitu/p/7661767.html
Copyright © 2011-2022 走看看