2018中国大学生程序设计竞赛

Tree and Permutation

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


Problem Description
There are N vertices connected by N1 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 ( 1N105 ) .
For the next N1 lines, each line contains three integer XY and L, which means there is an edge between X-th vertex and Y-th of length L ( 1X,YN,1L109 ) .
 
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个点的排列写出来,容易发现每两个点的最小路径对答案贡献了2*(n-1)!*dis[i][j]

  所以求一遍每两个点的最短路径,即2*(n-1)!*dis[i][j]

  求任意两点的最短路径参考博客:https://blog.csdn.net/acmore_xiong/article/details/51958921

AC代码:

#pragma comment(linker, "/STACK:102400000,102400000")
#include<iostream>
#include<vector>
#include<memory.h>
using namespace std;
#define ll long long
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 1e5+10;

struct nd
{
    int v,len;
};
vector<nd>vet[N];
long long n,dp[N],sum[N],c[N];

void DFS(int rt,int fa)
{
    sum[rt]=1;
    for(int i=0; i<vet[rt].size(); i++)
    {
        int son=vet[rt][i].v;
        int len=vet[rt][i].len;
        if(son==fa) continue;
        DFS(son,rt);
        (sum[rt]+=sum[son])%=mod;
        dp[rt]+=(dp[son]+(sum[son]*(n-sum[son]))%mod*len%mod)%mod;
        dp[rt] = (dp[rt]+mod)%mod;
    }
}

void init() {
    memset(sum,0,sizeof(sum));
    memset(dp,0,sizeof(dp));
}

void solve() {
    ll u,v,len;
    while(cin>>n)
    {
        for(int i=0; i<=n; i++)vet[i].clear();
        for(int i=1; i<=n-1; i++)
        {
            cin>>u>>v>>len;
            u--,v--;
            nd p1,p2;
            p1.v=v,p2.v=u;
            p1.len=p2.len=len;
            vet[u].push_back(p1);
            vet[v].push_back(p2);
        }
        init();
        DFS(0,-1);
        cout<<dp[0]*c[n]%mod<<endl;
    }
}



int main()
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    c[2]=2;
    for(int i=3;i<N;i++) c[i]=(i-1)*c[i-1]%mod;
    solve();
    return 0;
}

  

原文地址:https://www.cnblogs.com/l609929321/p/9535072.html