Tree and Permutation
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 821 Accepted Submission(s): 292
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
题意是给定一棵树,跑出n的全排列,每个全排列求出相应的路程,最后求得总和。
第一组示例是跑3的全排列,1->2->3 路径2,1->3->2 路径3,2->1->3 路径3,2->3->1路径3,3->1->2 路径3,3->2->1路径 2.
最后得到路径总和16。
此题就是对每条路径计数,求每条路径一共走了多少次,每条路径走的次数就是这条边上面的点数*这条边下面的点数*2*(n-1)!.
DFS做一下计数,最后得到结果相加。
代码实现:
/*
Look at the star
Look at the shine for U
*/
#include<bits/stdc++.h>
#define ll long long
#define PII pair<int,int>
#define sl(x) scanf("%lld",&x)
using namespace std;
const int N = 1e6+5;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1);
ll inv(ll b){if(b==1)return 1; return (mod-mod/b)*inv(mod%b)%mod;}
ll fpow(ll n,ll k){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%mod;n=n*n%mod;}return r;}
struct node{
int u,v,next,index;
}p[N];
int fa[N],n,ans,head[N],cnt;
ll fac[N],val[N];
void add(int u,int v,int num)
{
p[cnt].v = v;
p[cnt].index = num;
p[cnt].next = head[u];
head[u] = cnt++;
}
int dfs(int u,int f)
{
int sum = 0;
for(int i = head[u];~i;i = p[i].next)
{
if(p[i].index != f) sum += dfs(p[i].v,p[i].index);
}
return fa[f] = sum+1;
}
int main()
{
ll i,j,k,t,x,y,z;
fac[0] = 1;
for(i = 1;i <= 100005;i++) fac[i] = fac[i-1]*i%mod;
while(~sl(n))
{
for(i = 0;i <= n;i++) head[i] = -1;
memset(fa,0,sizeof(fa));
cnt = 0;
for(i = 1;i <= n-1;i++)
{
sl(x);sl(y);sl(val[i]);
add(x,y,i);
add(y,x,i);
}
ans = 0;
dfs(1,0);
for(i = 1;i <= n-1;i++)
{
ll u = fa[i];
ll v = n-fa[i];
// cout<<u<<"***"<<v<<endl;
ans = (u*v%mod*2%mod*val[i]%mod*fac[n-1]%mod+ans)%mod;
}
printf("%lld\n",ans);
}
}