[Codeforces 440D]Berland Federalization

Posted Mrsrz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Codeforces 440D]Berland Federalization相关的知识,希望对你有一定的参考价值。

题目大意:给你一棵n个节点的树,现在要你删除尽可能少的边,使得剩余一个节点数刚好为k的子树。你需要输出节点数和删除的边的编号。

解题思路:树形dp。

设dp[i][j]和v[i][j]表示以i为根的子树中删除j个节点最少删的边数,和其所需删除的边对应的(点,删除的节点个数),用一个pair存储。

那么转移状态的时候类似于背包问题。

dp[i][j]=min{dp[s][k]+dp[i][j-k]}(s为i的儿子)。

更新答案的同时暴力更新v即可。

最后搜索根,注意如果根不为1,则需要把根与它的父亲的连边也去掉,即答案要+1。

时间复杂度$O(n^3)$。

C++ Code:

#include<cstdio>
#include<cctype>
#include<vector>
#include<cstring>
#define N 405
using namespace std;
vector<pair<int,int> >v[N][N],G[N];
int n,k,fa[N],sz[N],dp[N][N];
inline int readint(){
	char c=getchar();
	for(;!isdigit(c);c=getchar());
	int d=0;
	for(;isdigit(c);c=getchar())
	d=(d<<3)+(d<<1)+(c^‘0‘);
	return d;
}
void dfs(int now,int pre){
	sz[now]=1;
	for(int i=0,s=G[now].size();i<s;++i){
		int to=G[now][i].first;
		if(to!=pre){
			dfs(to,now);
			fa[to]=G[now][i].second;
			sz[now]+=sz[to];
		}
	}
}
void dfs2(int now,int pre){
	if(now==1)dp[now][sz[now]]=0;else{
		dp[now][sz[now]]=1;
		v[now][sz[now]].clear();
		v[now][sz[now]].push_back(make_pair(now,sz[now]));
	}
	dp[now][0]=0;
	for(int i=0,s=G[now].size();i<s;++i){
		int to=G[now][i].first;
		if(to!=pre){
			dfs2(to,now);
			for(int j=sz[now];j;--j)
			for(int k=0;k<=sz[to]&&k<=j;++k)
			if(dp[now][j]>dp[to][k]+dp[now][j-k]){
				dp[now][j]=dp[to][k]+dp[now][j-k];
				v[now][j]=v[now][j-k];
				v[now][j].push_back(make_pair(to,k));
			}
		}
	}
}
void print(int now,int p){
	if(sz[now]==p){
		printf("%d ",fa[now]);
		return;
	}
	for(int i=0,s=v[now][p].size();i<s;++i)
	print(v[now][p][i].first,v[now][p][i].second);
}
int main(){
	n=readint(),k=readint();
	for(int i=1;i<n;++i){
		int x=readint(),y=readint();
		G[x].push_back(make_pair(y,i));
		G[y].push_back(make_pair(x,i));
	}
	memset(dp,0x3f,sizeof dp);
	fa[1]=0;
	dfs(1,0);
	dfs2(1,0);
	int ans=dp[1][n-k],rt=1;
	for(int i=2;i<=n;++i)
	if(sz[i]>=k&&dp[i][sz[i]-k]+1<ans){
		ans=dp[i][sz[i]-k]+1;
		rt=i;
	}
	printf("%d\n",ans);
	if(rt!=1)printf("%d ",fa[rt]);
	print(rt,sz[rt]-k);
	return 0;
}

以上是关于[Codeforces 440D]Berland Federalization的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces-B. Berland National Library(模拟)

codeforces 723D: Lakes in Berland

(KMPdp)Codeforces Educational Codeforces Round 21 G-Anthem of Berland

CodeForces 723D Lakes in Berland

模拟Codeforces 691A Fashion in Berland

codeforces 638B—— Making Genome in Berland——————类似拓扑排序