• HDU6446 Tree and Permutation(树上DP)


    传送门:点我

    Tree and Permutation

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

    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,1L10^9 ) .
     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个顶点,后面n-1行代表边的两个端点和边的权值。
             要输出的是n个顶点全排列对所有情况,按点依次访问的时候,经过的权值和。
             比如说样例1:
             三个顶点,即对1,2,3全排列,共有6种方式。(1->2->3,1->3->2.......)
             按每种情况的访问点的顺序累加权值。
    • 思路:
             这题考虑的是每条边对答案的贡献。
             考虑顶点有n个的情况:
             假设顶点x和顶点y有边相连,那么在全排列中这条边会被访问几次?
    •  固定x,对其余所有顶点进行全排列,得到(n-1)!种情况。
    • 固定y,对其余所有顶点进行全排列,得到(n-1)!种情况。
             显而易见,每条边在全排列中贡献了2*(n-1)!次,再乘上每2个点的最小路径dis[x][y],就是每条边对答案的贡献,即2*(n-1)!*dis[x][y]
             任意两点距离最短路径参考HDU5723  HDU2376
    代码:
    #include<bits/stdc++.h>
    #define LL long long
    #define pb push_back
    #define mk make_pair
    #define pill pair<int, int>
    #define mst(a, b)    memset(a, b, sizeof a)
    #define REP(i, x, n)    for(int i = x; i <= n; ++i)
    #define pi acos(-1.0)
    #define Max_N 1001
    #define  inf 0x3f3f3f3f      
    using namespace std;
    const LL mod = 1e9+7;
    LL dp[100005];
    int sum[100005];
    int n;
    vector<pair<int,LL> >v[100005];
    LL f[100005];
    void dfs(int now,int father){
        sum[now] = 1;
        for(int i = 0 ; i < v[now].size() ;  i++){
            int son = v[now][i].first;
            LL  len = v[now][i].second;
            if(son == father)continue;
            dfs(son,now);
            sum[now] += sum[son];
            dp[now]  += (dp[son]+((n-sum[son])%mod*sum[son])%mod*len%mod*2LL*f[n-1]%mod)%mod;
            dp[now] = (dp[now]+mod)%mod;
        }
    }
    int main()
    {
        f[0]=0 ; f[1] = 1;
        for(int i = 2 ; i <= 100000; i ++){
            f[i]=(f[i-1]*i)%mod;
        }
        while(~scanf("%d",&n)){
            memset(dp,0,sizeof(dp));
            memset(sum,0,sizeof(sum));
            for(int i = 0 ; i <= n ; i++)v[i].clear();
            for(int i = 0 ; i < n-1; i ++){
                int x,y;
                LL w;
                scanf("%d %d %lld",&x,&y,&w);
                v[x].push_back(make_pair(y,w));
                v[y].push_back(make_pair(x,w));
            }
            dfs(1,-1);
            printf("%lld
    ",dp[1]);
        }
    }
    /*
    3
    1 2 1
    2 3 1
    3
    1 2 1
    1 3 2
    */
  • 相关阅读:
    CSS:命名规范心得分享
    css中用一张背景图做页面的技术有什么优势?
    ie8 css hack
    简单介绍几个CSSReset的方法
    牛人也得看的CSS常识
    DIV+CSS网页布局常用的一些基础知识整理
    font-size:100%有什么作用?
    为什么无法定义1px左右高度的容器
    Div+CSS常见错误总结
    从数字千分位处理认识(?<=)、(?=)、(?:)
  • 原文地址:https://www.cnblogs.com/Esquecer/p/10477477.html
Copyright © 2020-2023  润新知