HDU 6446 Tree and Permutation(思维)

Tree and Permutation

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 284    Accepted Submission(s): 92


 

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(n<=1e5)个点,n-1条边。每条边有权值w。

1~n  这n个数可以产生n!个全排列。

对于某个全排列,比如2413  我们计算一个值,这个值为 树中2号节点到4号节点的距离+4号节点到1号节点的距离+1号节点到3号节点的距离

求所有排列 的这个值的和。

思路:考虑每条边(u,v,w),对于n个节点除去u,v有n-2个节点形成全排列(n-2)!种,然后将(u,v)放到n-2个节点的全排列的n-1个空中,共有(n-2)!*(n-1)=(n-1)!种。由于还要计算(v,u),所以再乘2。这是方法数,再乘以该边边权,再乘这条边两边的点的数量之积就是这条边对整个全排列的值的贡献。然后别忘了long long和取模就可以了。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=200010;
const ll mo=1e9+7;
int n,m,q,tot,tot2,cnt,tmp;
int he[maxn],f;
bool us[maxn];
ll sz[maxn],jc[maxn],dp[maxn],ans;
struct node
{
    int v;
    int nex;
    ll w;
}a[maxn];
void init()
{
    f=0;
    memset(he,-1,sizeof(he));
    memset(us,0,sizeof(us));
}
void add(int u,int v,ll w)
{
    a[f].v=v;
    a[f].w=w;
    a[f].nex=he[u];
    he[u]=f++;
}
int dfs(int u)
{
    sz[u]=1;us[u]=1;
    for(int i=he[u];i!=-1;i=a[i].nex)
    {
        int v=a[i].v;
        if(us[v])continue;
        sz[u]+=dfs(v);
        ans=(ans+sz[v]*((ll)n-sz[v])%mo*a[i].w%mo)%mo;
    }
    return sz[u];
}
int main()
{
    int T,cas=1;
    jc[0]=1;
    jc[1]=1;
    jc[2]=2;
    for(ll i=3;i<maxn;i++)
    jc[i]=(jc[i-1]*(i-1))%mo;
    while(scanf("%d",&n)!=EOF){
    init();
    for(int i=1;i<=n-1;i++)
    {
        int x,y;ll z;
        scanf("%d%d%lld",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    ans=0;
    dfs(1);
    //cout<<ans<<" * "<<jc[n]<<endl;
    ans=ans*jc[n]%mo;
    printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LSD20164388/article/details/82055591
今日推荐