【树形dp】VK Cup 2012 Round 1 D. Distance in Tree

统计树中长度为K的路径条数。

用f[u][k]表示从u结点的子树中出发,终止于u结点的长度为k的路径条数。

边dp边统计答案。为了防止重复统计,在枚举子节点的时候,先将该子节点和当前u结点(和前面已经统计过的子节点)的dp值统计到ans以后,

再把该子节点的dp值加到u结点的dp值中去。

这样,我们统计经过某个结点的长度为K的路径条数的时候,可以保证路径的两个端点来自其两个不同的子树或其本身,这样也是为了防止重复统计。

#include<cstdio>
using namespace std;
int n,m,ans;
int f[50010][510];
int v[100010],next[100010],first[50010],e;
void AddEdge(int U,int V){
	v[++e]=V;
	next[e]=first[U];
	first[U]=e;
}
int fa[50010];
void dfs(int U){
	f[U][0]=1;
	for(int i=first[U];i;i=next[i]){
		if(!fa[v[i]]){
			fa[v[i]]=U;
			dfs(v[i]);
			for(int j=0;j<m;++j){
				ans+=f[v[i]][j]*f[U][m-j-1];
			}
			for(int j=0;j<m;++j){
				f[U][j+1]+=f[v[i]][j];
			}
		}
	}
}
int main(){
//	freopen("cf161d.in","r",stdin);
	int x,y;
	scanf("%d%d",&n,&m);
	for(int i=1;i<n;++i){
		scanf("%d%d",&x,&y);
		AddEdge(x,y);
		AddEdge(y,x);
	}
	fa[1]=-1;
	dfs(1);
	printf("%d\n",ans);
	return 0;
}
时间: 2024-10-01 06:53:02

【树形dp】VK Cup 2012 Round 1 D. Distance in Tree的相关文章

[树形DP]VK Cup 2012 Round 1 D. Distance in Tree

题意: 给出一棵树,然后问任意两点间距离为k的情况有多少种. 分析: 显然是DP,但是状态方程如何向呢?一棵树,肯定是先从根节点开始考虑情况,那么就把每个点看做是一课子树,然后dp[i][j] 表示计算到i点时距离为k的情况的种类数.然后扫描该点的子节点,递归,完了之后 ans+=dp[x][j-1]*dp[v][k-j]; 表示到i节点的距离和到子节点中的距离==k-1的所有情况,为什么是k-1 ,而不是k呢,因为x和子节点之间还有一条边的长度,然后更新x节点. 这里累加答案和更新x的顺序很重

DP VK Cup 2012 Qualification Round D. Palindrome pairs

题目地址:http://blog.csdn.net/shiyuankongbu/article/details/10004443 1 /* 2 题意:在i前面找回文子串,在i后面找回文子串相互配对,问有几对 3 DP:很巧妙的从i出发向两头扩展判断是否相同来找回文串 4 dpr[i] 代表记录从0到i间的回文子串的个数,dpl[i] 代表记录i之后的回文子串个数 5 两两相乘就行了 6 详细解释:http://blog.csdn.net/shiyuankongbu/article/details

【树形dp】Codeforces Round #405 (rated, Div. 1, based on VK Cup 2017 Round 1) B. Bear and Tree Jumps

我们要统计的答案是sigma([L/K]),L为路径的长度,中括号表示上取整. [L/K]化简一下就是(L+f(L,K))/K,f(L,K)表示长度为L的路径要想达到K的整数倍,还要加上多少. 于是,我们现在只需要统计sigma((L+f(L,K))),最后除以K即可. 统计sigma(L)时,我们考虑计算每条边出现在了几条路径中,设u为edgei的子节点,那么这条边对答案的贡献就是siz(u)*(n-siz(u)),siz(u)为u的子树大小. 统计sigma(f(L,K))时,我们需要dp出

VK Cup 2015 - Round 2 B. Work Group

题解: 树形dp 首先开始做时我以为只要贪心选取就可以了... 后来发现根节点可以不用选,而选和为奇数的满足条件的子节点. 所以需要重新构建状态 dp[u][0]表示满足条件的以u为根节点的子树中,节点数为偶数的最大值 dp[u][0]表示满足条件的以u为根节点的子树中,节点数为奇数的最大值 最开始不选根节点.dp[u][0]=0,dp[u][1]为-INF(不存在) 每次加子节点v时 1.偶可以由偶(u)+偶(v),奇(u)+奇(v)更新 2.奇可以由奇(u)+奇(v),奇(u)+奇(v)更新

VK Cup 2012 Qualification Round 2 C. String Manipulation 1.0 字符串模拟

C. String Manipulation 1.0 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 codeforces.com/problemset/problem/91/B Description One popular website developed an unusual username editing procedure. One can change the username only by deleting some characte

VK Cup 2012 Qualification Round 1 C. Cd and pwd commands 模拟

C. Cd and pwd commands Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/158/C Description Vasya is writing an operating system shell, and it should have commands for working with directories. To begin with, he dec

Codeforces Round #412 (rated, Div. 2, base on VK Cup 2017 Round 3) B. T-Shirt Hunt

B. T-Shirt Hunt time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard output Not so long ago the Codecraft-17 contest was held on Codeforces. The top 25 participants, and additionally random 25 participant

Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition)

A. Bear and Game 题意:一个体育节目,它可能在某一分钟是很有趣的,其他时间都是很无聊的,如果持续十五分钟都很无聊的话那么Bear就会关掉电视,问什么时候会关掉电视. 题解:用第i个有趣的时间减去第i-1个有趣的时间,如果差值大于十五分钟那就输出第i个有趣的时间+15.注意第一个有趣的时间要为0,最后一个为90. 代码: 1 /*A*/ 2 #include<cstdio> 3 using namespace std; 4 5 const int maxn=95; 6 7 int

Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) B

Description Bear Limak examines a social network. Its main functionality is that two members can become friends (then they can talk with each other and share funny pictures). There are n members, numbered 1 through n. m pairs of members are friends.