统计树中长度为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