Distance in Tree CodeForces, distancecodeforces
Distance in Tree CodeForces-161D
For a tree with n nodes, the distance between any two points is 1. Now it is a bit u, v, and the shortest distance between u and v is k, calculate the number of such points (u, v) (u, v)/(v, u) as a pair ).
Method:
Ans [I] [k] indicates the number of subnodes whose distance from the I node is k.
Ans [I) [k] = sum {ans [son] [k-1]}
Ans [I] [0] = 1
Sum [I] indicates that (u, v) is the subnode of I and the shortest path of (u, v) is over I.
Sum [I] = sum {ans [I] [p] * ans [I] [k-p]} // incorrect.
Sum [I] = sum {ans [son] [p] * sum {ans [otherson] [k-p-2]} // pair, but too slow
Sum [I] = sum {ans [son] [p] * (ans [I] [k-p-1]-ans [son] [k-p-2])} // rewrite (unexpected)
Because (u, v)/(v, u) is a pair, the actual I-point-related answer (that is, an endpoint is I-point, or (u, v) and (u, v) Shortest Path over I point) is:
$ Ans [I] [k] + sum [I]/2 $
Because you do not need to separate the points, you can directly add these values with an ans without 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 }