P1272 重建道路

题目描述

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

输入输出格式

输入格式:

第1行:2个整数,\(N\)和\(P\)

第\(2..N\)行:每行2个整数\(I\)和\(J\),表示节点\(I\)是节点\(J\)的父节点。

输出格式:

单独一行,包含一旦被破坏将分离出恰含\(P\)个节点的子树的道路的最小数目。


最近很颓,这个还算裸的树形DP也卡了我好长时间。


首先明确一点(卡了我好久),这是一颗树,根是可以随便选的。

如果只按照题目把树输入是会大的(然而数据水只错了两个点)


令\(dp[i][j]\)代表根节点为\(i\)的子树在失去(注意是失去)\(j\)个点时 切掉的边的最小个数。

\(dp[i][j]=min(dp[i][j],dp[i][j-k]+dp[i_{son}][k])\)

  • 注意:这个已经滚动掉了一维(第几个子树) 枚举\(j\)时要倒着哦

有个问题,对于直接切掉自己儿子的情况怎么办?

最开始时我这样做了,在每次枚举\(j\)的时候

\(dp[i][j]=min(dp[i][j],dp[i][j-size[i_{son}]]+1);\)

然而这样做是重复了的。(想想看)

有个很喵(妙)的做法。

在\(dfs\)每次求完\(i\)时把她自己切掉就好了啦 -> \(dp[i][size[i]]=1\);

回到最开始,虽然根不确定,其实只需要随便取一种根的情况就行拉。

比如说\(root\)是根,\(dp[root][n-p]\)肯定不包含切她自己的情况

我们就在其他节点中,把自己切成一棵树,即用\(dp[i][p-(n-size[i])]+1\)更新\(ans\)

#include <cstdio>
#include <cstring>
int min(int x,int y) {return x<y?x:y;}
const int N=156;
int dp[N][N];//子树i舍弃j个点的最小切割数
int n,p,root;
int g[N][N],used[N],size[N];

void dfs(int now)
{
    dp[now][0]=0;
    for(int i=1;i<=n;i++)//枚举子树
        if(g[now][i])
        {
            dfs(i);
            size[now]+=size[i];
            int r=min(p,size[now]);
            for(int j=r;j>=1;j--)//枚举当前舍弃节点数
            {
                int r2=min(min(p,size[i]),j);
                for(int k=1;k<=r2;k++)//枚举子树状态
                    dp[now][j]=min(dp[now][j],dp[now][j-k]+dp[i][k]);
            }
        }
    dp[now][++size[now]]=1;
}

int main()
{
    memset(dp,0x3f,sizeof(dp));
    scanf("%d%d",&n,&p);
    int u,v;
    p=n-p;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d",&u,&v);
        g[u][v]=1;
        used[v]=1;
    }
    for(int i=1;i<=n;i++)
        if(!used[i])
        {
            root=i;
            break;
        }
    dfs(root);
    int ans=0x3f3f3f3f;
    for(int i=1;i<=n;i++)
    {
        if(i==root) {ans=min(ans,dp[i][p]);continue;}
        int tt=p+size[i]-n;//还要砍得
        if(tt>=0) ans=min(ans,dp[i][tt]+1);
    }
    printf("%d\n",ans);
    return 0;
}

2018.5.6

洛谷 P1272 解题报告的更多相关文章

  1. 洛谷 P1462 解题报告

    P1462 通往奥格瑞玛的道路 题目背景 在艾泽拉斯大陆上有一位名叫歪嘴哦的神奇术士,他是部落的中坚力量 有一天他醒来后发现自己居然到了联盟的主城暴风城 在被众多联盟的士兵攻击后,他决定逃回自己的家乡 ...

  2. 洛谷 P1879 解题报告

    P1879 [USACO06NOV]玉米田Corn Fields 题目描述 农场主\(John\)新买了一块长方形的新牧场,这块牧场被划分成\(M\)行\(N\)列\((1 ≤ M ≤ 12; 1 ≤ ...

  3. 洛谷 P1069 解题报告

    P1069 细胞分裂 题目描述 \(Hanks\)博士是\(BT\) (\(Bio-Tech\),生物技术) 领域的知名专家.现在,他正在为一个细胞实验做准备工作:培养细胞样本. \(Hanks\) ...

  4. 洛谷 P2491 解题报告

    P2491 消防 题目描述 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个 ...

  5. 洛谷 P2587 解题报告

    P2587 [ZJOI2008]泡泡堂 题目描述 第XXXX届NOI期间,为了加强各省选手之间的交流,组委会决定组织一场省际电子竞技大赛,每一个省的代表队由n名选手组成,比赛的项目是老少咸宜的网络游戏 ...

  6. 洛谷 P1054 解题报告

    P1054 等价表达式 题目描述 明明进了中学之后,学到了代数表达式.有一天,他碰到一个很麻烦的选择题.这个题目的题干中首先给出了一个代数表达式,然后列出了若干选项,每个选项也是一个代数表达式,题目的 ...

  7. 洛谷 P1053 解题报告

    P1053 篝火晚会 题目描述 佳佳刚进高中,在军训的时候,由于佳佳吃苦耐劳,很快得到了教官的赏识,成为了"小教官".在军训结束的那天晚上,佳佳被命令组织同学们进行篝火晚会.一共有 ...

  8. 洛谷 P1057 解题报告

    P1057 传球游戏 题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹 ...

  9. 洛谷 P1430 解题报告

    P1430 序列取数 题目描述 给定一个长为\(n\)的整数序列\((n<=1000)\),由\(A\)和\(B\)轮流取数(\(A\)先取).每个人可从序列的左端或右端取若干个数(至少一个), ...

随机推荐

  1. Python学习笔记 - dict和set

    dict #!/usr/bin/env python3 # -*- coding: utf-8 -*- #dict >>> d = {'Michael': 95, 'Bob': 75 ...

  2. oozie note

    http://blog.sina.com.cn/s/blog_62a9902f01011ccd.html 实例:http://www.infoq.com/cn/articles/oozieexampl ...

  3. python 多窗口编辑

    同时打开多个文件: 1,vim filename1 filename2 在打开的多个文件中 :next 转到下个文件中 :prev 转到上个文件中 :last/:first 分别到最后一个和第一个文件 ...

  4. Dynamics CRM2011 同一个FORM表单同一个字段可以摆放多次

    这是一个很细微的问题,细微到很容易被忽略(可能其他人没有但我确实是忽略了) 红框中的勾默认是勾选的,可能有人会像我一样,从没关心过这个地方还有个勾也从没关心过要把这个勾去掉,所以在表单上A.B两个节中 ...

  5. Linux下使用GDAL进行开发(automake使用)

    首先写三个源代码文件,分别是GDALTest.cpp.Fun.cpp和Fun.h,将这三个存放在一个叫GDALTest的文件夹中,然后打开终端,切换到该目录,如下图所示(注:这个图是最后截图的,所以文 ...

  6. 【翻译】了解ASP.NET MVC中的Ajax助手

    原文:Understanding AJAX Helpers in ASP.NET MVC 作者: Shailendra Chauhan works as Software Analyst at rep ...

  7. Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  8. 如何调整DOS窗口的宽高

    运行->cmd->dos窗口上沿点右键->默认值所选字体字体: 新宋体大小: 13窗口大小宽度: 100高度: 40屏幕缓冲区大小宽度: 100高度: 300 在这里还可以设置依他常 ...

  9. 脚本自动化 ant

    用ant,shell下也可以用make. 1,ant 是一个自动化编译工具,安装使用. 2,编写build.xml,核心,写明进行哪些操作,删,建,编译,javac,java等,从例子可以看出每个操作 ...

  10. Android ViewPager和Slidingmenu手势冲突问题

    尊重原创:  http://blog.csdn.net/sk719887916/article/details/40043961 skay 想必大家都遇到过手势和焦点的问题   对于安卓初学者或者初次 ...