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);
}
P1272的更多相关文章
- 洛谷 P1272 解题报告
P1272 重建道路 题目描述 一场可怕的地震后,人们用\(N\)个牲口棚\((1≤N≤150\),编号\(1..N\))重建了农夫\(John\)的牧场.由于人们没有时间建设多余的道路,所以现在从一 ...
- 洛谷 P1272 重建道路 解题报告
P1272 重建道路 题目描述 一场可怕的地震后,人们用\(N\)个牲口棚\((1≤N≤150\),编号\(1..N\))重建了农夫\(John\)的牧场.由于人们没有时间建设多余的道路,所以现在从一 ...
- P1272 重建道路(树形dp)
P1272 重建道路 题目描述 一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟 ...
- 洛谷 P1272 重建道路(树形DP)
P1272 重建道路 题目描述 一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟 ...
- [洛谷P1272] 重建道路
类型:树形背包 传送门:>Here< 题意:给出一棵树,要求断开$k$条边来分离出一棵有$P$个节点的子树.求最小的$k$ 解题思路 和上一题类型相同,但不那么好做了——分离出的一棵子树肯 ...
- P1272 重建道路
题目描述 一场可怕的地震后,人们用N个牲口棚(1≤N≤150,编号1..N)重建了农夫John的牧场.由于人们没有时间建设多余的道路,所以现在从一个牲口棚到另一个牲口棚的道路是惟一的.因此,牧场运输系 ...
- 【洛谷P1272】道路重建
题目大意:给定一个 N 个节点的树,求至少剪掉多少条边才能使得从树中分离出一个大小为 M 的子树. 题解:考虑树形 dp,定义 \(dp[u][i][t]\) 为以 u 为根节点与前 i 个子节点构成 ...
- luogu P1272 重建道路
嘟嘟嘟 这好像是一种树上背包. 我们令dp[i][j] 表示在 i 所在的子树中(包括节点 i)分离出一个大小为 j 的子树最少需割多少条边. 那么转移方程就是 dp[u][j] = min(dp[u ...
- 洛谷 P1272 重建道路
题目链接 题解 树形dp \(f_{i, j}\)表示以\(i\)为根的子树切出联通块大小为\(j\)的最小答案 显然\(f[i][1]\)为与\(i\)连的边数 设\(v\)是\(u\)的儿子 那么 ...
随机推荐
- java多线程之线程组与线程池
看这篇文章:http://blog.csdn.net/zen99t/article/details/50909099
- VS2010中VC++目录和C/C++之间的区别。VC++ Directories和C/C++的区别。
首先,这是个历史遗留问题,说起来比较复杂.其次,这个问题在微软的MSDN博客上已经专门被说起过了,英文好的请直接移步到原文:<VC++ Directories>.另外,stack over ...
- 资料收集:学习 Linux/*BSD/Unix 的 30 个最佳在线文档
文章转自:https://linux.cn/article-10311-1.html 手册页(man)是由系统管理员和 IT 技术开发人员写的,更多的是为了作为参考而不是教你如何使用.手册页对于已经熟 ...
- 【卷土重来之C#学习笔记】(二)c#编程概述
(1)开始C#,一个简单的程序Hello Word 开始 using System; //使用了System的命名空间 using System.Collections.Generic; us ...
- json数据的存储与读取
1. json数据格式: data = [ {"key1":"xxx","item":"ddd"}, {"k ...
- 【VirtualBox】快照
一.快照备份 虚拟机系统快照下来,以后就可以恢复到快照之前的系统 右上角->虚拟电脑工具->快照
- [LeetCode]22. Generate Parentheses括号生成
Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...
- poi学习
需要节点 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</a ...
- JS构造函数(便于理解,简易)
* 构造函数: * 1.构造函数的函数名最好首字母大写(否则 WebStorm 编辑器会提示报错) * 2.自己的对象多次被复制 * 3.构造函数里可以创建公有属性.公有方法.私有属性和私有方法 * ...
- Elipse plugin or Bundle & OSGI
Develop and register service, lookup and use service! Android Design on service's publish-find-bind ...