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. 洛谷 P1272 重建道路(树形DP)

    P1272 重建道路 题目描述 一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟 ...

  2. [洛谷P1272] 重建道路

    类型:树形背包 传送门:>Here< 题意:给出一棵树,要求断开$k$条边来分离出一棵有$P$个节点的子树.求最小的$k$ 解题思路 和上一题类型相同,但不那么好做了——分离出的一棵子树肯 ...

  3. 洛谷 P2505 [HAOI2012]道路 解题报告

    P2505 [HAOI2012]道路 题目描述 C国有n座城市,城市之间通过m条单向道路连接.一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小.两条最短路不同,当且仅当它 ...

  4. 洛谷 P1272 重建道路

    题目链接 题解 树形dp \(f_{i, j}\)表示以\(i\)为根的子树切出联通块大小为\(j\)的最小答案 显然\(f[i][1]\)为与\(i\)连的边数 设\(v\)是\(u\)的儿子 那么 ...

  5. 洛谷 P1783 海滩防御 解题报告

    P1783 海滩防御 题目描述 WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和仓库总是被敌方派人偷袭 ...

  6. 洛谷 P4597 序列sequence 解题报告

    P4597 序列sequence 题目背景 原题\(\tt{cf13c}\)数据加强版 题目描述 给定一个序列,每次操作可以把某个数\(+1\)或\(-1\).要求把序列变成非降数列.而且要求修改后的 ...

  7. 洛谷1087 FBI树 解题报告

    洛谷1087 FBI树 本题地址:http://www.luogu.org/problem/show?pid=1087 题目描述 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全 ...

  8. 【洛谷P1272】道路重建

    题目大意:给定一个 N 个节点的树,求至少剪掉多少条边才能使得从树中分离出一个大小为 M 的子树. 题解:考虑树形 dp,定义 \(dp[u][i][t]\) 为以 u 为根节点与前 i 个子节点构成 ...

  9. 洛谷 P3313 [SDOI2014]旅行 解题报告

    P3313 [SDOI2014]旅行 题目描述 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教 ...

随机推荐

  1. 从Mongo导出数据库到Excel

    在MongoDB的安装目录的bin文件夹下打开命令行: ./mongoexport -d kugou_db -c songs -f rank,singer,song,time --type=csv - ...

  2. 自签名证书 nginx tomcat

    给Nginx配置一个自签名的SSL证书 - 廖雪峰的官方网站 https://www.liaoxuefeng.com/article/0014189023237367e8d42829de24b6eaf ...

  3. IdentityServer4【Introduction】之包和项目构建

    包和项目构建 IdentityServer包含了以下的nuget包: IdentityServer4 nuget | github 这个包包含了IdentityServer核心的组成部分,有对象模型, ...

  4. mysql [assword expired

    mysql 5.6 在使用Navicat在其他机器上进行远程登录数据库时 会出现 password expired ,需要重新设置一下密码. SET PASSWORD FOR 'root'@'%' = ...

  5. CRM/PLM/SCM/MES与ERP的联系与区别

    企业通过专设信息机构.信息主管,配备适应现代企业管理运营要求的自动化.智能化.高技术硬件.软件.设备.设施,建立包括网络.数据库和各类信息管理系统在内的工作平台,提高企业经营管理效率的发展模式. 那么 ...

  6. python爬虫之git的使用(github的使用)

    上面博文中我们简单的了解了一下基本的git操作,但是我们都是将代码放到了本地的仓库里面,但是如果我们是一个团队开发的话,肯定不会放到每个人的本地,必须得有个统一的地方存放代码,国外的大家都在使用git ...

  7. centos6.8 安装wget

    1.执行yum -y install wget 提示:没有相应的包.原因:默认最小化安装没有装wget,而且默认源中没有wget,所以只能先切换源配置. (1)下载.阿里的源配置,并放到/etc/yu ...

  8. Ansible入门与实践

    一.ansible介绍 Ansible是一个简单的自动化运维管理工具,基于Python语言实现,由Paramiko和PyYAML两个关键模块构建,可用于自动化部署应用.配置.编排task(持续交付.无 ...

  9. peewee 事物 回滚

    peewee 事物 回滚 #!/usr/bin/env python # coding=utf-8 from peewee import * db = MySQLDatabase(host='123. ...

  10. vue 思維導圖

    vue概念:vue是一個輕量級的javascript庫:是一種漸進式的框架:vue可以實現數據視圖雙向綁定. vue基礎語法:實例化.條件.循環 vue重頭戲:動畫.組件.過濾.ajax.自定義組件. ...