2018中国大学生程序设计竞赛 - 网络选拔赛 I Tree and Permutation (dfs计数)

版权声明:欢迎转载,请注明此博客地址。 https://blog.csdn.net/Ever_glow/article/details/82083298

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

扫描二维码关注公众号,回复: 3417057 查看本文章

题意是给定一棵树,跑出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);
	}
}

猜你喜欢

转载自blog.csdn.net/Ever_glow/article/details/82083298