BZOJ 2435 [Noi2011]道路修建

题解:

计算每条边的贡献即可

用BFS

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=1000009;

int n;
long long ans=0;
int idp[maxn],cnt=0;

int cntedge=0;
int head[maxn]={0};
int to[maxn<<1],nex[maxn<<1],dist[maxn<<1];
void Addedge(int x,int y,int z){
    nex[++cntedge]=head[x];
    to[cntedge]=y;
    dist[cntedge]=z;
    head[x]=cntedge;
}

int Myabs(int x){
    if(x<0)return -x;
    else return x;
}

int siz[maxn];
int father[maxn];

queue<int>q;
void Bfs(){
    q.push(1);
    while(!q.empty()){
        int x=q.front();q.pop();
        idp[++cnt]=x;
        for(int i=head[x];i;i=nex[i]){
            if(to[i]==father[x])continue;
            father[to[i]]=x;
            q.push(to[i]);
        }
    }
}

int rd(){
    int r=0,k=1;
    char c=getchar();
    for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
    for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';
    return r*k;
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n-1;++i){
        int x=rd(),y=rd(),z=rd();
        Addedge(x,y,z);
        Addedge(y,x,z);
    }
    Bfs();
    for(int i=1;i<=n;++i)siz[i]=1;
    for(int i=n;i>=1;--i){
        int x=idp[i];
        siz[father[x]]+=siz[x];
    }
    for(int x=1;x<=n;++x){
        for(int i=head[x];i;i=nex[i]){
            if(to[i]==father[x])continue;
            ans+=1LL*Myabs(n-siz[to[i]]*2)*dist[i];
        }
    }
    cout<<ans<<endl;
    return 0;
}

 

posted @ 2018-03-25 23:26  ws_zzy  阅读(132)  评论(0编辑  收藏  举报