• P1272


    P1272 重建道路

    题目描述

    一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场。由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的。因此,牧场运输系统可以被构建成一棵树。John想要知道另一次地震会造成多严重的破坏。有
    些道路一旦被毁坏,就会使一棵含有P(1≤P≤N)个牲口棚的子树和剩余的牲口棚分离,John想知道这些道路的最小数目。

    ps:原本想的是(f[i][j])表示以第(i)个点为根的子树,出来(j)个点的断掉的最小道路

    (f[u][k]=min(f[u][k],f[u][k-j]+f[v][j]))
    然后输出(min(f[1][p],f[1][size[1]-p]))

    苦于(N)次60分以后。我猛然地从题解中发现。我的答案计算写错了。

    有可能整棵树中。在某一个子树中就已经将答案取出来了,然后没有记录。

    所以我们就应该在计算中即时记录

    #include<cstdio>
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    using std::min;
    const int maxn=160;
    struct node
    {
        int p;
        int nxt;
    };
    node line[maxn<<1];
    int head[maxn],tail;
    int son[maxn];
    int f[maxn][maxn];
    int n,p,ans=0x7fffffff;
    /*void dfs(int now,int fa)
    {
        f[now][0]=0;
        son[now]=1;
        for(int I=head[now];I;I=line[I].nxt)
        {
            if(line[I].p==fa)   continue;
            dfs(line[I].p,now);
            son[now]+=son[line[I].p];
            for(int i=son[now]-1;i>=1;i--)
                for(int j=0;j<=son[line[I].p]&&j<=i;j++)
                    f[now][i]=min(f[now][i],f[now][i-j]+f[line[I].p][j]);
        }
        f[now][son[now]]=1;
        return ;
    }*/
    void dfs(int now,int fa)
    {
        son[now]=1;
        for(int i=head[now];i;i=line[i].nxt)
            if(line[i].p!=fa)
            {
                dfs(line[i].p,now);
                son[now]+=son[line[i].p];
            }
        f[now][0]=0;
        f[now][son[now]]=1;
    }
    void Dfs(int now,int fa)
    {
        for(int I=head[now];I;I=line[I].nxt)
        {
            if(line[I].p==fa)   continue;
            Dfs(line[I].p,now);
            for(int i=son[now]-1;i;i--)
                for(int j=0;j<=i;j++)
                    f[now][i]=min(f[now][i],f[now][i-j]+f[line[I].p][j]);
        }
        if(son[now]>=p)
            ans=min(ans,f[now][son[now]-p]+f[now][son[now]]);
    }
    void add(int a,int b)
    {
        line[++tail].p=b;
        line[tail].nxt=head[a];
        head[a]=tail;
    }
    int main()
    {
        memset(f,1,sizeof(f));
        scanf("%d%d",&n,&p);
        int a,b;
        for(int i=1;i<n;i++)
        {
            scanf("%d%d",&a,&b);
            add(a,b);
            add(b,a);
        }
        dfs(1,0);
        f[1][0]=f[1][son[1]]=0;
        Dfs(1,0);
        printf("%d",ans);
    }
    
    
  • 相关阅读:
    使用Sed抽取MySQL安装文档的目录及行号
    [MySQL]关于Com_状态
    [译]理解对象存储如何工作
    [译]OpenStack Object Storage Monitoring
    通过设置swift中container的ACL提供匿名访问及用户授权读取服务
    使用swift命令遭遇503错误
    swift-get-nodes简单使用
    修改虚拟硬盘的大小
    php-fpm重启
    Windows学习"Network Analysis in Python"
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/9721096.html
Copyright © 2020-2023  润新知