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