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

    题目描述

    给定一棵树。要求往树中加入一些边使得从1到其他节点的距离至多是2 。 输出加入边的最小数量。(边全部都是无向的)

    题解:好多人都说是贪心,但是我写的是树形dp。

    (这道题实在太像小胖守皇宫了)

    先贪一步,每条边都由1连出,另一端距离为1。因此可以更新其父亲和儿子。

    dp[ u ][ 0 / 1 / 2]:u点由自己/儿子/父亲更新。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 200050
    int n,hed[N],cnt;
    struct EG
    {
        int to,nxt;
    }e[2*N];
    void ae(int f,int t)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        hed[f] = cnt;
    }
    int dp[N][3];
    void dfs(int u,int fa)
    {
        dp[u][0]=1;
        int mn = 0x3f3f3f3f,y=1;
        for(int j=hed[u];j;j=e[j].nxt)
        {
            int to = e[j].to;
            if(to==fa)continue;
            y=0;
            dfs(to,u);
            dp[u][0]+=min(dp[to][0],min(dp[to][1],dp[to][2]));
            dp[u][2]+=min(dp[to][0],dp[to][1]);
            dp[u][1]+=min(dp[to][0],dp[to][1]);
            if(mn>dp[to][0]-dp[to][1])mn=dp[to][0]-dp[to][1];
        }
        if(mn>0)dp[u][1]+=mn;
        if(y)dp[u][1]=0x3f3f3f3f;
    }
    int main()
    {
        scanf("%d",&n);
        for(int f,t,i=1;i<n;i++)
        {
            scanf("%d%d",&f,&t);
            ae(f,t),ae(t,f);
        }
        dfs(1,0);
        int ans = 0;
        for(int j=hed[1];j;j=e[j].nxt)
        {
            int to = e[j].to;
            ans+=dp[to][0]-1;
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9833081.html
Copyright © 2011-2022 走看看