题目大意:
  给你一棵树,你可以删掉一些边,使得分除去的子树中至少有一棵大小为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. HDU 1045 Fire Net (深搜)

    题目链接 Problem DescriptionSuppose that we have a square city with straight streets. A map of a city is ...

  2. DataFrame衍生新特征操作

    1.DataFrame中某一列的值衍生为新的特征 #将LBL1特征的值衍生为one-hot形式的新特征 piao=df_train_log.LBL1.value_counts().index #先构造 ...

  3. layui利用jQuery设置下拉列表的值

    今天在利用jQuery动态设置下拉列表的值的时候确怎么也赋值不上去,其中用到了layui框架,源代码如下: $.post(contextPath+'/courseLibrary/getCourseBa ...

  4. Ajax请求数据与删除数据后刷新页面

    1.ajax异步请求数据后填入模态框 请求数据的按钮(HTML) <a class="queryA" href="javascript:void(0)" ...

  5. 如何通过掩码计算可用的IP数量

    假设掩码是28,28也就是28个1.本身掩码是255.255.255.255那么转换成二进制也就是 11111111,11111111,11111111,11111111 那么28个1也就是: 111 ...

  6. Spring之IOC,DI,动态代理,反射

    Spring框架是J2EE开发中一个使用广泛的框架,它使得dao和service层的维护更加便利.Spring框架有两个重要的特征,一个是IOC,另一个是AOP.我们在这里主要介绍IOC,以及IOC中 ...

  7. Oracle创建WM_CONCAT函数

    Oracle创建WM_CONCAT函数 WM_CONCAT这个函数会出错,所以从 11g开始.官方不认可 WM_CONCAT.然后就没这个函数了, 下面就是创建WM_CONCAT这个函数的步骤 第一步 ...

  8. java网络编程三次握手四次挥手

    第一次握手:client设置syn=1,随机产生一个序列号seq=x,将数据包发送到server.client进入syn_send状态, 等待server确认. 第二次握手:server查看clien ...

  9. 服务器fsockopen函数和pfsockopen函数开启及作用

    摘要: fsockopen()函数的作用是可以用来打开一个socket连接,另一个函数pfsockopen()也有相似的功能,只不过后者是一个“持续”(persistent)的fsockopen()函 ...

  10. CentOS7.5安装Mysql5.7.22

    一 下载 下载地址:https://www.mysql.com/downloads/ 1 点击第一个链接地址,进入MySQL官方网站,单击“Downloads”下载Tab页,进入下载界面 2 找到Co ...