bzoj2435[Noi2011]道路修建

bzoj2435[Noi2011]道路修建

题意:

给个n点树,每条边的费用为这条边两端的节点数的差值*这条边的长度,求这个数的总费用。

题解:

水题,dfs求出节点的子树大小sz,对于每一条边,费用为深度大的sz值与n-sz相减的绝对值乘边的长度。

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define inc(i,j,k) for(int i=j;i<=k;i++)
 5 #define maxn 1000010
 6 #define ll long long
 7 using namespace std;
 8 
 9 struct e{int t,n;}; e es[maxn*2]; int g[maxn],ess;
10 void pe(int f,int t){
11     es[++ess]=(e){t,g[f]}; g[f]=ess; es[++ess]=(e){f,g[t]}; g[t]=ess;
12 }
13 int f[maxn],t[maxn],sz[maxn],n,dep[maxn]; ll w[maxn],ans;
14 inline int read(){
15     char ch=getchar(); int f=1,x=0;
16     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
17     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
18     return f*x;
19 }
20 void dfs(int x,int fa){
21     sz[x]=1;
22     for(int i=g[x];i;i=es[i].n)if(es[i].t!=fa)dep[es[i].t]=dep[x]+1,dfs(es[i].t,x),sz[x]+=sz[es[i].t];
23 }
24 int main(){
25     n=read(); inc(i,1,n-1)f[i]=read(),t[i]=read(),w[i]=(ll)read(),pe(f[i],t[i]); dfs(1,0); ll ans=0;
26     inc(i,1,n-1){
27         if(dep[f[i]]<dep[t[i]])swap(f[i],t[i]); ans+=(ll)abs(sz[f[i]]-(n-sz[f[i]]))*w[i];
28     }
29     printf("%lld",ans); return 0;
30 }

 

20160611

posted @ 2016-08-16 23:08  YuanZiming  阅读(191)  评论(0编辑  收藏  举报