Distance in Tree CodeForces - 161D
For a tree with n nodes, the distance between any two points is 1. Now it is a little u, v, and the shortest distance between u and V is k. The number of such pairs of points ((u,v)/(v,u) is calculated as a pair.
Method:
ans[i][k] denotes the number of sub-nodes whose distance from I node is k
ans[i][k]=sum{ans[son][k-1]}
ans[i][0]=1
sum[i] denotes that (u,v) are subnodes of I and the shortest path of (u,v) passes through I
sum[i]=sum{ans[i][p]*ans[i][k-p]} // / No, there will be more on the same chain.
sum[i]=sum{ans[son][p]*sum{ans[otherson][k-p-2]} // Yes, but it's too slow.
sum[i]=sum{ans[son][p]*(ans[i][k-p-1]-ans[son][k-p-2])}// alternative (I didn't think of it)
Since (u,v)/(v,u) is a pair, the answer to point I (that is, an endpoint is point i, or (u,v) is a sub-node of point I and the shortest path of (u,v) crosses point i) is:
$ans[i][k]+sum[i]/2$
Since it is not necessary to remember each point separately, we can add these values directly with an ans instead of opening sum.
1 #include<cstdio> 2 #include<vector> 3 using namespace std; 4 typedef long long LL; 5 struct Edge 6 { 7 LL to,next; 8 }edge[100001]; 9 LL first1[50010],num_edge; 10 LL ans[50001][501]; 11 LL ans1,ans2,n,k2; 12 bool vis[50001]; 13 void dfs(LL u) 14 { 15 LL k=first1[u],i,j; 16 vector<LL> temp; 17 ans[u][0]=1; 18 vis[u]=true; 19 while(k!=0) 20 { 21 LL &v=edge[k].to; 22 if(!vis[v]) 23 { 24 dfs(v); 25 for(i=1;i<=k2;i++) 26 ans[u][i]+=ans[v][i-1]; 27 temp.push_back(v); 28 } 29 k=edge[k].next; 30 } 31 ans2+=ans[u][k2]; 32 for(i=0;i<temp.size();i++) 33 for(j=0;j<=k2-2;j++) 34 ans1+=ans[temp[i]][j]*(ans[u][k2-j-1]-ans[temp[i]][k2-j-2]); 35 } 36 int main() 37 { 38 LL i,a,b; 39 scanf("%I64d%I64d",&n,&k2); 40 for(i=1;i<n;i++) 41 { 42 scanf("%I64d%I64d",&a,&b); 43 edge[++num_edge].to=b; 44 edge[num_edge].next=first1[a]; 45 first1[a]=num_edge; 46 edge[++num_edge].to=a; 47 edge[num_edge].next=first1[b]; 48 first1[b]=num_edge; 49 } 50 dfs(1); 51 printf("%I64d",ans2+ans1/2); 52 return 0; 53 }