zoukankan      html  css  js  c++  java
  • hdu6446 Tree and Permutation 2018ccpc网络赛 思维+dfs

    题目传送门

    题目描述:给出一颗树,每条边都有权值,然后列出一个n的全排列,对于所有的全排列,比如1 2 3 4这样一个排列,要算出1到2的树上距离加2到3的树上距离加3到4的树上距离,这个和就是一个排列的val,计算所有全排列的val和就可以了。

    思路:对于一个n的全排列,会发现 任意x-y的边在这个全排列中出现的次数是一样的,(x-y和y到x是不一样的边)。也就是说我只需要计算出这个次数,然后再乘以所有边的总和(所有x-y和y-x的和)就可以了。

    次数就是 frac{n!*(n-1)}{n*(n-1)/2},(边的总数除以边的种类)化简一下就是(n-1)!*22*(n-1)!。

    而边的和怎么计算呢,考虑树上的某一条边,这条边在边的总和中出现的次数,就是这条边两个节点的子节点个数相乘。所以dfs一遍就可以算出sum。

    这道题还要取模,由于我们算次数的公式没有化简,用逆元算,然后逆元的板子有一部分没取模,wa到死。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<string.h>
    #include<sstream>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    #include<stack>
    #include<bitset>
    #define CLR(a,b) memset(a,b,sizeof(a))
    using namespace std;
    typedef long long ll;
    const int maxn=100010;
    ll mod=1e9+7;
    int head[maxn*2];
    struct edge{
    	int v,Next;
    	ll w;
    }a[maxn*2];
    int tot;
    inline void addv(int u,int v,ll w){
    	a[++tot].v=v;
    	a[tot].Next=head[u];
    	a[tot].w=w;
    	head[u]=tot;
    }
    int n,u,v;
    ll w,sum,f[maxn];
    inline void init(){
    	tot=0,sum=0;
    	CLR(head,-1);
    	for(int i=1;i<=n;i++)f[i]=1;
    }
    inline ll dfs(int x,int fa){
    	for(int i=head[x];i!=-1;i=a[i].Next){
    		int v=a[i].v;
    		if(v==fa)continue;
    		f[x]=(f[x]+dfs(v,x))%mod;
    		sum=(sum+2*a[i].w%mod*f[v]%mod*((ll)n-f[v]))%mod;
    	}
    	
    	return f[x];
    }
    int main(){
    	while(cin>>n){
    		init();
    		for(int i=1;i<n;i++){
    			scanf("%d%d%lld",&u,&v,&w);
    			addv(u,v,w);
    			addv(v,u,w);
    		}
    		dfs(1,-1);
    		ll an=1;
    		for(int i=n-1;i>1;i--){
    			an=(an*i)%mod;
    		}
    		printf("%lld
    ",sum*an%mod);
    	}
    }

    Tree and Permutation

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


     

    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

  • 相关阅读:
    ssm依赖
    NSNotificationCenter详解
    Objective-C语法之代码块(block)的使用
    IOS UI UITableView
    IOS 多线程(4) --线程通讯
    IOS 多线程(3) --线程安全
    IOS 多线程(2) --NSThread
    IOS 多线程(1) --基础知识
    IOS UI TextFiled常用总结
    IOS UI TabBar标签栏的使用
  • 原文地址:https://www.cnblogs.com/mountaink/p/9536701.html
Copyright © 2011-2022 走看看