HDU - 6446

题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/weixin_43826249/article/details/107754047