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 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.
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 ) .
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个点的排列写出来,容易发现每两个点的最小路径对答案贡献了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; }