链接:https://ac.nowcoder.com/acm/contest/992/J?&headNav=acm
来源:牛客网
题目描述
红红和蓝蓝是随机降生在苹果树上的苹果仙灵,现在红线仙想估测他们的CP系数,并决定是否使他们成为一对CP。
给出n个结点n-1条边的树,节点编号为1到n,定义distance(i,j)为i与j的树上距离。
CP系数是指所有红红和蓝蓝在不同位置i,j的distance(i,j)之和。
即∑n−1i=1∑nj=i+1distance(i,j)
求红红和蓝蓝的CP系数,对10^9+7取模。
输入描述:
第一行一个整数n( 1 < n <= 10^5 ),表示树的结点个数。
随后n-1行,每行三个整数a,b,c ( 1 <= a,b <= n ),( 0 <= c <= 10^9 ),表示结点a,b之间有一条权值为c的边,( a ≠ b )。
输出描述:
一行一个整数,表示CP系数对10^9+7取模的结果。
示例1
输入
复制
4
1 2 1
2 3 1
2 4 1
输出
复制
9
说明
distance(1,2)=1
distance(1,3)=2
distance(1,4)=2
distance(2,3)=1
distance(2,4)=1
distance(3,4)=2
CP系数=(1+2+2+1+1+2)%(10^9+7)=9
将一条边删去后,分成的两棵子树内的点都需要经过这条边才能到达另一棵子树,它对结果的贡献为
左端结点个数∗右端节点个数∗权值
鲲神的树就是nb
//摸鲲神
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
const int mod=1e9+7;
struct node{
int v,w;
node(){
}
node(int _v,int _w){
v=_v;
w=_w;
}
};
int num[N];
vector<node> G[N];
int n;
ll ans=0;
void dfs(int u,int fa){
num[u]=1;
for(int i=0;i<G[u].size();i++){
int v=G[u][i].v;
if(v==fa) continue;
dfs(v,u);
ans+=(ll)num[v]*(n-num[v])%mod*G[u][i].w%mod;
ans%=mod;
num[u]+=num[v];
}
}
int main(){
scanf("%d",&n);
for(int i=1;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
G[u].push_back(node(v,w));
G[v].push_back(node(u,w));
}
dfs(1,0);
printf("%lld\n",ans);
return 0;
}