Distance in Tree CodeForces - 161D

Keywords: C++

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 }

Posted by mattyj10 on Fri, 08 Feb 2019 21:12:17 -0800