hdoj6446 (tree DP)

Topic link: https: //vjudge.net/problem/HDU-6446

Question is intended: to simplify the problem is to compute the distance and the intended 2 * (n-1) times!.

Ideas:

  DP simple tree, and the contributions calculated distance, the edge (u, v) is sz [v] * by summing the contribution of each side (n-sz [v]).

#include<cstdio>
#include<algorithm>
using namespace std;

typedef long long LL;
const int maxn=1e5+5;
const int MOD=1e9+7;
int n,cnt,head[maxn],sz[maxn];
LL ans;

struct node{
    int v,nex;
    LL w;
}edge[maxn<<1];

void adde(int u,int v,LL w){
    edge[++cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].nex=head[u];
    head[u]=cnt;
}

void dfs(int u,int fa){
    sz[u]=1;
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v;
        if(v==fa) continue;
        dfs(v,u);
        sz[u]+=sz[v];
        ans=(ans+edge[i].w*sz[v]%MOD*(n-sz[v])%MOD)%MOD;
    }
}

int main(){
    while(~scanf("%d",&n)){
        ans=0;
        cnt=0;
        for(int i=1;i<=n;++i)
            head[i]=0;
        for(int i=1;i<n;++i){
            int u,v;LL w;
            scanf("%d%d%lld",&u,&v,&w);
            adde(u,v,w);
            adde(v,u,w);
        }
        dfs(1,0);
        for(int i=1;i<n;++i)
            ans=ans*i%MOD;
        ans=ans*2%MOD;
        printf("%lld\n",ans);
    }
    return 0;
}

 

  Moreover, because a few days ago to learn the partition, you can expect to see this problem in dotted rule and seek distance. In practice, all the points by obtaining the center of gravity of u to find the center of gravity distance dis [i], and then written using the second partition of the point, traverse all the sub-nodes u v, with the sum of the calculated distance indicates that sum, NUM represents the number of nodes in the front, then the current iteration of dis [i], which contribute to the num * dis [i] + sum. But be careful not to leak the center of gravity for the endpoint side, it will initialize num 1, not 0.

  Dotted rule Code:

#include<cstdio>
#include<algorithm>
using namespace std;

typedef long long LL;
const int maxn=1e5+5;
const int MOD=1e9+7;
const int inf=0x3f3f3f3f;
int n,cnt,head[maxn],sz[maxn],mson[maxn],Min,size,root;
int vis[maxn],t,num;
LL dis[maxn],tmp,sum,ans;

struct node{
    int v,nex;
    LL w;
}edge[maxn<<1];

void adde(int u,int v,LL w){
    edge[++cnt].v=v;
    edge[cnt].w=w;
    edge[cnt].nex=head[u];
    head[u]=cnt;
}

void getroot(int u,int fa){
    sz[u]=1,mson[u]=0;
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v;
        if(vis[v]||v==fa) continue;
        getroot(v,u);
        sz[u]+=sz[v];
        mson[u]=max(mson[u],sz[v]);
    }
    mson[u]=max(mson[u],size-sz[u]);
    if(mson[u]<Min) Min=mson[u],root=u;
}

void getdis(int u,int fa,LL len){
    dis[++t]=len;
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v;
        if(vis[v]||v==fa) continue;
        getdis(v,u,(len+edge[i].w)%MOD);
    }
}

void solve(int u){
    sum=0;
    num=1;
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v;
        if(vis[v]) continue;
        t=0;
        tmp=0;
        getdis(v,u,edge[i].w);
        for(int i=1;i<=t;++i){
            ans=(ans+num*dis[i]%MOD+sum)%MOD;
            tmp=(tmp+dis[i])%MOD;
        }
        sum=(sum+tmp)%MOD;
        num+=t;
    }
}

void fenzhi(int u,int ssize){
    vis[u]=1;
    solve(u);
    for(int i=head[u];i;i=edge[i].nex){
        int v=edge[i].v;
        if(vis[v]) continue;
        Min=inf,root=0;
        size=sz[v]<sz[u]?sz[v]:(ssize-sz[u]);
        getroot(v,0);
        fenzhi(root,size);
    }
}

int main(){
    while(~scanf("%d",&n)){
        cnt=0;
        ans=0;
        for(int i=1;i<=n;++i)
            head[i]=vis[i]=0;
        for(int i=1;i<n;++i){
            int u,v;LL w;
            scanf("%d%d%lld",&u,&v,&w);
            adde(u,v,w);
            adde(v,u,w);
        }
        Min=inf,root=0,size=n;
        getroot(1,0);
        fenzhi(root,n);
        for(int i=1;i<n;++i)
            ans=ans*i%MOD;
        ans=ans*2%MOD;
        printf("%lld\n",ans);
    }
    return 0;
}
View Code

 

Guess you like

Origin www.cnblogs.com/FrankChen831X/p/11420582.html