题目链接:HDU - 6446
考虑每条边的使用次数。
显然只有1-2,2-3,3-4这样穿过才是合法的,一共有 n-1 对。
然后我们可以从子树当中选一个位置,和非子树的选一个位置,然后其他的随便放。
AC代码:
#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5+10,mod=1e9+7;
int n,res,f[N],sz[N];
int head[N],nex[N<<1],to[N<<1],w[N<<1],tot;
inline void add(int a,int b,int c){to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot;}
void dfs(int x,int fa){
sz[x]=1;
for(int i=head[x];i;i=nex[i]) if(to[i]!=fa){
dfs(to[i],x); sz[x]+=sz[to[i]];
res=(res+w[i]*sz[to[i]]%mod*(n-sz[to[i]])%mod*f[n-1]%mod);
}
}
void solve(){
res=0; tot=0; memset(head,0,sizeof head);
for(int i=1,a,b,c;i<n;i++) scanf("%lld %lld %lld",&a,&b,&c),add(a,b,c),add(b,a,c);
dfs(1,0); printf("%lld\n",res*2%mod);
}
signed main(){
f[0]=1; for(int i=1;i<N;i++) f[i]=f[i-1]*i%mod;
while(cin>>n) solve();
return 0;
}