• P1272 重建道路


      一开始状态定义错了……所以没有对qwq,以及有几个坑qwq……

      首先 f [ i ] [ j ] 表示以 i 为根的子树,切除 j 个节点所需要切除的最小边数,而我一开始定义的是表示以 i 为根的子树,切除后生成一颗有 j 个节点的子树,所需要切除的最小边数。

      为什么我的不行呐?因为对于一个新的子节点更新状态,它能生成多大的子树其实是和父亲节点是没有关系的,即它与父亲节点原来的状态无关也,两棵树不也连通,然而对于切除多少点,我们在意的是切除后剩的,而不是切除的。那么最后的ans就是 f [ ... ] [ num - p ] + f [ ... ] [ num [ ... ] ]了。 

      以及,根节点的 f [ ] num是0,因为它没有父亲节点本身就是一颗含有 num 个点的(子)树。

      代码如下:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define maxn 2000
    struct node
    {
        int to,nxt;
    } edge[maxn];
    int f[maxn][maxn],num[maxn],head[maxn];
    int n,p,cnt,ans=999999999;
    void add(int a,int b)
    {
        edge[++cnt].to=b;
        edge[cnt].nxt=head[a];
        head[a]=cnt;
    }
    void dfs(int u,int fa)
    {
        num[u]=1;
        for(int i=head[u]; i; i=edge[i].nxt)
        {
            int tot=0,am=0;
            int v=edge[i].to;
            if(v==fa) continue;
            dfs(v,u);
            num[u]+=num[v];
            f[u][num[v]]=1;
            am+=num[v];
            f[u][am]=++tot;
        }
        f[u][num[u]]=1;
        f[u][0]=0;
        if(u==1) f[u][num[u]]=0;
    }
    void dp(int u,int fa)
    {
        for(int i=head[u]; i; i=edge[i].nxt)
        {
            int v=edge[i].to;
            if(v==fa) continue;
            dp(v,u);
            for(int j=num[u]; j>=0; j--)
                for(int k=0; k<=j; k++)
                    f[u][j]=min(f[u][j],f[u][j-k]+f[v][k]);
        }
        if(num[u]>=p)
            ans=min(ans,f[u][num[u]-p]+f[u][num[u]]);
    }
    int main()
    {
        memset(f,0x3f3f3f3f,sizeof(f));
        scanf("%d%d",&n,&p);
        for(int i=1; i<n; i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs(1,0);
        dp(1,0);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    实体类字段格式校验
    .Net Core之自定义中间件
    创建型之【单例模式】
    Linux下安装Apollo (Quick Start)
    Linux下安装MySQL你又踩过多少坑【宇宙最全教程】
    C#之Expression表达式目录树
    创建型之【建造者模式】
    [LeetCode] 1675. Minimize Deviation in Array
    [LeetCode] 1996. The Number of Weak Characters in the Game
    [LeetCode] 1523. Count Odd Numbers in an Interval Range
  • 原文地址:https://www.cnblogs.com/popo-black-cat/p/10337025.html
Copyright © 2020-2023  润新知