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 }