poj1947——rebuilding roads
来源:互联网 发布:mac 屏幕录像 编辑:程序博客网 时间:2024/05/17 23:26
题目大意:给出一棵树,问最少减去几条边,能得到一个有p个结点的子树
输入:原树结点个数n p(1<=n<=150)
结点i(父亲) i的儿子j
输出:最少减去的边数
分析:树形动态规划
状态dp[i][j]:以i为根节点,要得到j个结点的子树去掉的最少边数(注意子树中包含i结点)
状态转移方程:对于结点i,要么删掉它的某个儿子c,即删掉i_c一条边,要么在以c为根的子树中选出一些边删掉,构造出有k个结点的子树,所以方程为dp[i][j]=min{dp[i][j]+1,dp[i][j-k]+dp[c][k]},c为i的儿子
结果:min{dp[root][p],dp[i][p]+1},i为除了根节点的其他结点
初始化:dp[i][1]=i结点的儿子个数(要只剩一个结点即i本身,就要剪掉i的所有儿子)
代码:转载自http://www.cnblogs.com/20143605--pcx/p/5348610.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# include<iostream>
# include<cstdio>
# include<cstring>
# include<vector>
# include<algorithm>
using
namespace
std;
const
int
N=155;
const
int
INF=1000000000;
int
n,m;//结点个数,要得到的子树结点个数
bool
flag[N];//标志是否有父节点
int
dp[N][N];
vector<
int
>e[N];
void
init()
{
int
a,b;
for
(
int
i=1;i<=n;++i){
e[i].clear();
for
(
int
j=0;j<=m;++j)
dp[i][j]=INF;
}
memset
(flag,
false
,
sizeof
(flag));
for
(
int
i=1;i<n;++i){
scanf
(
"%d%d"
,&a,&b);
e[a].push_back(b);
flag[b]=
true
;
}
}
void
dfs(
int
u)
{
dp[u][1]=0;
for
(
int
i=0;i<e[u].size();++i){
int
v=e[u][i];
dfs(v);
for
(
int
j=m;j>=1;--j){
dp[u][j]+=1;//直接减去子树v的情况,去掉的边数+1
for
(
int
k=1;k<j;++k){
///k从1循环到j-1,一定不能从0循环到j
dp[u][j]=min(dp[u][j],dp[v][k]+dp[u][j-k]);//以v结点为根得到k个结点的子树
}
}
}
}
void
solve()
{
int
ans=INF;
for
(
int
i=1;i<=n;++i){
if
(flag[i])
continue
;//找到整棵树的根节点
dfs(i);//遍历根节点
ans=dp[i][m];
break
;
}
for
(
int
i=1;i<=n;++i)
ans=min(ans,dp[i][m]+1);//除了根节点以外的其他任意结点想要成为独立的根,都要剪掉与总根之间的边,所以要+1
printf
(
"%d\n"
,ans);
}
int
main()
{
while
(~
scanf
(
"%d%d"
,&n,&m))
{
init();
solve();
}
return
0;
}
阅读全文
0 0
- poj1947——rebuilding roads
- POJ1947 Rebuilding Roads
- POJ1947--Rebuilding Roads
- poj1947 Rebuilding Roads
- poj1947 Rebuilding Roads
- poj1947 Rebuilding Roads
- POJ1947 Rebuilding Roads(树状DP)
- POJ1947 Rebuilding Roads 树形DP
- POJ1947:Rebuilding Roads(树形DP)
- POJ1947:Rebuilding Roads(树形DP)
- poj1947 Rebuilding Roads 树形dp
- poj1947 Rebuilding Roads 树形背包
- poj1947--Rebuilding Roads(树状dp)
- [POJ1947]Rebuilding Roads解题报告
- poj1947 Rebuilding Roads--树形dp
- POJ1947 Rebuilding Roads 树形DP
- POJ1947 Rebuilding Roads【树形DP】
- 树形DP(4) Poj1947 Rebuilding Roads
- C#流总结(文件流、内存流、网络流、BufferedStream、StreamReader/StreamWriter、TextReader/TextWriter)
- IOS开发--微信支付
- 织梦去掉最后一个循环符号“|”的代码
- 计算机网络面试知识点【一】
- 深入理解C#的装箱和拆箱
- poj1947——rebuilding roads
- 【基础】ABAP不同变量类型之间数值大小比较
- 网易前端面试题总结,你见过几个?——爱创课堂
- 刚买的服务器mysql自动停止
- 上台阶案例(递归和非递归实现,斐波那契)
- 常用NMEA0183的报文解析
- 傻瓜式学习webpack(二)——配置webpack
- Failed to contact Jack server
- 禁止类的拷贝构造函数和赋值操作符