题目大意:
  给你一棵树,你可以删掉一些边,使得分除去的子树中至少有一棵大小为k。
  问最少删去多少边,以及删边的具体方案。

思路:
  树形DP。
  f[i][j]表示以i为根,子树中去掉j个点最少要删边的数量;
  v[i][j]表示其具体方案。
  然后对每个点跑一下背包。
  状态转移方程f[x][k+j]=min{f[x][k]+f[y][j]|y为x子结点}。
  注意y的不同状态不能同时对x的同一个状态产生影响,所以转移的时候必须把数组复制一遍,将原数组和转移过后的数组隔离开来。
  v的转移只需要把v[x][k]和v[y][j]并起来就OK了。
  最后答案枚举每个结点的f[node][size[node]-k],如果不是一开始假定的根结点1,我们要将其与主树连接的边算入答案。

 #include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int inf=0x7fffffff;
const int N=;
struct Edge {
int to,id;
};
std::vector<Edge> e[N];
inline void add_edge(const int &u,const int &v,const int &i) {
e[u].push_back((Edge){v,i});
e[v].push_back((Edge){u,i});
}
int size[N],f[N][N];
int t[N],pre[N];
std::vector<int> v[N][N];
void dfs(const int &x,const int &par) {
size[x]=;
int eid;
for(unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i].to;
if(y==par) {
eid=e[x][i].id;
continue;
}
pre[y]=e[x][i].id;
dfs(y,x);
size[x]+=size[y];
}
f[x][]=;
f[x][size[x]]=;
v[x][size[x]].push_back(eid);
std::fill(&f[x][],&f[x][size[x]],inf);
for(unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i].to;
eid=e[x][i].id;
if(y==par) continue;
memcpy(t,f[x],sizeof t);
for(int j=;j<=size[y];j++) {
for(int k=;k<size[x]-j;k++) {
if(f[x][k]==inf) continue;
if(f[x][k]+f[y][j]<t[k+j]) {
t[k+j]=f[x][k]+f[y][j];
v[x][k+j]=v[x][k];
v[x][k+j].insert(v[x][k+j].end(),v[y][j].begin(),v[y][j].end());
}
}
}
memcpy(f[x],t,sizeof t);
}
}
int main() {
int n=getint(),k=getint();
for(register int i=;i<n;i++) {
add_edge(getint(),getint(),i);
}
dfs(,);
int ans=f[][size[]-k],node=;
for(register int root=;root<=n;root++) {
if(size[root]<k) continue;
f[root][size[root]-k]++;
v[root][size[root]-k].push_back(pre[root]);
if(f[root][size[root]-k]<ans) {
ans=f[root][size[root]-k];
node=root;
}
}
printf("%d\n",ans);
for(register unsigned i=;i<v[node][size[node]-k].size();i++) {
printf("%d ",v[node][size[node]-k][i]);
}
return ;
}

[CodeForces-440D]Berland Federalization的更多相关文章

  1. Codeforces 440 D. Berland Federalization 树形DP,记录DP

    题目链接:http://codeforces.com/contest/440/problem/D D. Berland Federalization   Recently, Berland faces ...

  2. [Codeforces 1005F]Berland and the Shortest Paths(最短路树+dfs)

    [Codeforces 1005F]Berland and the Shortest Paths(最短路树+dfs) 题面 题意:给你一个无向图,1为起点,求生成树让起点到其他个点的距离最小,距离最小 ...

  3. CodeForces 567B Berland National Library

    Description Berland National Library has recently been built in the capital of Berland. In addition, ...

  4. Codeforces B - Berland National Library

    B. Berland National Library time limit per test 1 second memory limit per test 256 megabytes input s ...

  5. AC日记——codeforces Ancient Berland Circus 1c

    1C - Ancient Berland Circus 思路: 求出三角形外接圆: 然后找出三角形三条边在小数意义下的最大公约数; 然后n=pi*2/fgcd; 求出面积即可: 代码: #includ ...

  6. CodeForces - 1073D Berland Fair

    XXI Berland Annual Fair is coming really soon! Traditionally fair consists of nnbooths, arranged in ...

  7. Codeforces 1296F Berland Beauty

    题目链接:http://codeforces.com/problemset/problem/1296/F 思路: 1————2————3————4————5————6 1->3 2 2-> ...

  8. CodeForces 567B Berland National Library hdu-5477 A Sweet Journey

    这类题一个操作增加多少,一个操作减少多少,求最少刚开始为多少,在中途不会出现负值,模拟一遍,用一个数记下最大的即可 #include<cstdio> #include<cstring ...

  9. [Codeforces440D]Berland Federalization

    Problem 给你一棵树,最少删掉哪些边,能使得余下的至少有1个大小刚好为k的残树. 1 ≤ k ≤ n ≤ 400 Solution 用f[i][j]表示以i为根有j个节点的最少删边数量 因为此题 ...

随机推荐

  1. Linux必备工具Tmux

    之前介绍了Linux的Screen命令,今天介绍一个更为强大的终端工具Tmux. Tmux 是一个用于在一个终端窗口中运行多个终端会话的工具.它基本能替代nohup以及screen,甚至比它们更为强大 ...

  2. Hbuilder连接第3方模拟器(夜神)

    http://www.bcty365.com/content-146-5148-1.html

  3. linux内核数据结构之链表【转】

    转自:http://www.cnblogs.com/Anker/p/3475643.html 1.前言 最近写代码需用到链表结构,正好公共库有关于链表的.第一眼看时,觉得有点新鲜,和我之前见到的链表结 ...

  4. ubuntu的su初始密码设置

    Ubuntu刚安装后,不能在terminal中运行su命令,因为root没有默认密码,需要手动设定. 以安装ubuntu时输入的用户名登陆,该用户在admin组中,有权限给root设定密码. 给roo ...

  5. elasticsearch集群介绍及优化【转】

    elasticsearch用于构建高可用和可扩展的系统.扩展的方式可以是购买更好的服务器(纵向扩展)或者购买更多的服务器(横向扩展),Elasticsearch能从更强大的硬件中获得更好的性能,但是纵 ...

  6. 在shell中如何判断字符串是否为有效的IP地址【转】

    转自 在shell中如何判断字符串是否为有效的IP地址_echoisecho_新浪博客http://blog.sina.com.cn/s/blog_53a844e50100xxus.html 近来需要 ...

  7. 教你如何修改FireFox打开新标签页(NewTab Page)的行列数

    FireFox的打开新建标签页(即NewTab Page)默认只能显示3x3个网站缩略图,这9个自定义的网站,非常方便快捷,什么hao123的弱爆了,本人从未用过此类导航网站,曾经用过的也只是abou ...

  8. linux -j 4

    把源码编译成可执行的二进制文件, 4为服务器内核数

  9. CentOS 7.1使用yum安装MySql5.6.24

    http://www.cnblogs.com/yuanfeiblog/p/5276492.html

  10. 数据分析python应用到的ggplot

    数据分析中应用到python中的ggplot库,可以用来画图 数据之类的用优达学院中课程七中的数据为例 数据是:https://s3.amazonaws.com/content.udacity-dat ...