题目大意:
  给你一棵树,你可以删掉一些边,使得分除去的子树中至少有一棵大小为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. SQL server(到主机的TCPIPl连接失败的问题)

    1 首先要做的是在sql新建查询里输入 exec sys.sp_readerrorlog 0, 1, 'listening' 运行后 会显示你的sql 正在运行的tcp/ip接口 看看是否和你java ...

  2. INIT_WORK

    借助runtime pm,在需要使用模块时,增加引用计数(可调用pm_runtime_get),不需要使用时,减少引用计数(可调用pm_runtime_put). 1.INIT_WORK(struct ...

  3. angular项目文件概览

    在Mac上打开终端,输入ng new b-app  如下: 然后在webstorm中打开 src文件夹 你的应用代码位于src文件夹中. 所有的Angular组件.模板.样式.图片以及你的应用所需的任 ...

  4. 以应用带动SDN发展(CDN峰会 工信部杨崑)(转)

    以应用带动SDN发展(CDN峰会 工信部杨崑)   SDNAP推荐:这是在亚太全媒体SDN峰会由工信部研究院秘书长杨崑做的关于SDN的一个演讲,本人认为主讲者通过对整 个信息服务体系的精简归纳总结,剥 ...

  5. [ python ] 初始面向对象

    首先,通过之前学习的函数编写一个 人狗大战 的例子. 分析下这个需求,人 狗 大战  三个事情.角色:人.狗动作:狗咬人,人打狗 先创建人和狗两个角色: def person(name, hp, ag ...

  6. python【项目】:工资管理(简易版)

    功能要求: 登录系统用户认证通过后才能列出下一级菜单员工信息表 登录系统要有用户登录.注册账号.删除账号.修改密码.退出 登录密码要有加密功能 从info.txt文件读取员工及工资信息,最后通过增加, ...

  7. HDU 4553 约会安排(线段树区间合并+双重标记)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4553 题目大意:就是有三种操作: ①DS x,安排一段长度为x的空闲时间跟屌丝一起,输出这段时间的起点 ...

  8. 读书笔记|Windows 调试原理学习|持续更新

    关于调试方面的学习笔记,主要来源于<软件调试>的读书笔记和梦织未来论坛的视频教程 1.调试器使用一个死循环监听调试信息. DebugActiveProcess(PID);while(TRU ...

  9. 分布式跟踪系统zipkin+mysql

    1.初始化数据库: 1) CREATE TABLE IF NOT EXISTS zipkin_spans ( trace_id_high BIGINT NOT NULL DEFAULT 0 COMME ...

  10. vscode vue配置和一些其它辅助【工具篇】

    后续有补充就经常更新