Tree and Permutation
http://acm.hdu.edu.cn/showproblem.php?pid=6446
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1155 Accepted Submission(s): 416
Problem Description
There are N vertices connected by N−1 edges, each edge has its own length.
The set { 1,2,3,…,N } contains a total of N! unique permutations, let’s say the i-th permutation is Pi and Pi,j is its j-th number.
For the i-th permutation, it can be a traverse sequence of the tree with N vertices, which means we can go from the Pi,1-th vertex to the Pi,2-th vertex by the shortest path, then go to the Pi,3-th vertex ( also by the shortest path ) , and so on. Finally we’ll reach the Pi,N-th vertex, let’s define the total distance of this route as D(Pi) , so please calculate the sum of D(Pi) for all N! permutations.
Input
There are 10 test cases at most.
The first line of each test case contains one integer N ( 1≤N≤105 ) .
For the next N−1 lines, each line contains three integer X, Y and L, which means there is an edge between X-th vertex and Y-th of length L ( 1≤X,Y≤N,1≤L≤109 ) .
Output
For each test case, print the answer module 109+7 in one line.
Sample Input
3
1 2 1
2 3 1
3
1 2 1
1 3 2
Sample Output
16
24
Source
Recommend
chendu
思路:
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 10;
int a[maxn];
const ll mod = 1e9 + 7;
ll fac[maxn];
struct edge
{
int to,next;
ll w;
}e[maxn*2];
int head[maxn];
int tot;
int num[maxn];
ll dp[maxn];
ll ans;
void add(int u,int to,int w)
{
e[++tot].next=head[u];
e[tot].w=w;
e[tot].to=to;
head[u]=tot;
}
void init()
{
fac[0]=1;
fac[1]=1;
for(int i=2;i<maxn;i++)
{
fac[i]=fac[i-1]*i % mod;
}
}
int n;
void dfs(int u,int fa)
{
dp[u]=1;
for(int i=head[u];i!=0;i=e[i].next)
{
int v=e[i].to;
ll w=e[i].w;
if(v==fa) continue;
dfs(v,u);
//cout<<dp[v]<<endl;
dp[u]+=dp[v];
ans= (ans + dp[v]*(n-dp[v])%mod*w%mod)%mod;
}
}
int main()
{
init();
while(~scanf("%d",&n))
{
tot=0;
memset(head,0,sizeof(head));
memset(dp,0,sizeof(dp));
memset(num,0,sizeof(num));
for(int i=0;i<n-1;i++)
{
int u,v;
ll w;
scanf("%d%d%lld",&u,&v,&w);
num[u]++; num[v]++;
add(u,v,w);
add(v,u,w);
}
ans=0;
for(int i=1;i<=n;i++)
{
if(num[i]==1)
{
dfs(i,0); break;
}
}
ans=ans*2%mod*fac[n-1]%mod;
printf("%lld\n",ans);
}
return 0;
}