2435: [Noi2011]道路修建(树上操作)

2435: [Noi2011]道路修建

题目:传送门


 

题解:

   建完边之后以1为根建树,统计深度和各个点的子树大小(包括自己)

   询问的时候:答案=长度*abs(n-深度大的点的子树大小*2)

   ans+=a[i].c*abs(n-tot[y]*2)

 


代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long LL;
 8 struct node
 9 {
10     int x,y,c,next;
11 }a[2110000];int len,last[1110000];
12 int n,tot[1110000],dep[1110000];
13 void ins(int x,int y,int c)
14 {
15     len++;a[len].x=x;a[len].y=y;a[len].c=c;
16     a[len].next=last[x];last[x]=len;
17 }
18 void dfs(int x,int fa)
19 {
20     tot[x]=1;dep[x]=dep[fa]+1;
21     for(int k=last[x];k;k=a[k].next)
22     {
23         int y=a[k].y;
24         if(y!=fa)
25         {
26             dfs(y,x);
27             tot[x]+=tot[y];
28         }
29     }
30 }
31 int main()
32 {
33     scanf("%d",&n);len=0;memset(last,0,sizeof(last));
34     for(int i=1;i<n;i++)
35     {
36         int x,y,c;scanf("%d%d%d",&x,&y,&c);
37         ins(x,y,c);ins(y,x,c);
38     }
39     dfs(1,0);
40     LL ans=0;
41     for(int i=1;i<=len;i+=2)
42     {
43         int x=a[i].x,y=a[i].y;
44         if(dep[x]>dep[y])swap(x,y);
45         ans+=LL(a[i].c)*abs(n-tot[y]*2);
46     }
47     printf("%lld\n",ans);
48     return 0;
49 }

 

posted @ 2018-03-10 09:03  CHerish_OI  阅读(153)  评论(0编辑  收藏  举报