HDU 6446 Tree and Permutation [ 树形DP + DFS ]

题目链接:

HDU-6446 Tree and Permutation

题意概括:

有 N 个点,被 N - 1 条边相连通。对于点 1 - N 的序列的全排列,求出第一个点到其余点的最短路之和,并求出所有情况的和。

数据范围:

不超过 10 组测试数据

1\leq N\leq 10^{5}

1\leq X,Y\leq N,1\leq L\leq 10^{9}

题解分析:

由于是无环的联通图,这是一棵无根树。数据量很大,要是枚举点对来求的话,耗时太久

换一个思路,就是对于每条边,假如两条边的节点数分别为 A、B,则这条边对总和的贡献为 A*B*w。

明天再详细写。。

AC代码:

#include <stdio.h>
#include <vector>
#include <memory.h>
using namespace std;
const int MAXN = 1e5 + 10;
const int MOD = 1e9 + 7;
typedef long long ll;

struct edge {
    int v;      //终点
    int w;      //权重
};

vector<edge> tree[MAXN];
ll ans, fac[MAXN];
int cnt[MAXN], N;

void dfs(int cur, int father) {
    cnt[cur] = 1;
    for (int i = 0; i < tree[cur].size(); i++) {
        int son = tree[cur][i].v;
        if (son != father) {
            dfs(son, cur);
            cnt[cur] += cnt[son];
            ans = (ans + ((ll)cnt[son] * (N - cnt[son]) % MOD) * tree[cur][i].w % MOD) % MOD;
        }
    }
}

int main () {
    while (scanf("%d", &N) != EOF) {
        
        for (int i = 1; i <= N; i++) tree[i].clear();
        memset(cnt, 0, sizeof(cnt));
        ans = 0;
        
        int u, v, w;
        for (int i = 0; i < N -1; i++) {
            scanf("%d%d%d", &u, &v, &w);
            edge e1, e2;
            
            e1.v = v;
            e1.w = w;
            tree[u].push_back(e1);
            
            e2.v = u;
            e2.w = w;
            tree[v].push_back(e2);              //双向边
        }
        dfs(1, 0);                              //找一点作为根
        
        fac[1] = 1;
        for (int i = 2; i <= N - 1; i++)
            fac[i] = fac[i - 1] * i % MOD;
        
        ans = ans * fac[N - 1] % MOD * 2 % MOD;
        printf("%lld\n", ans);
    }
}

 

                                                 Tree and Permutation

                         Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

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≤10^{5} ) .
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≤10^{9} ) .

Output

For each test case, print the answer module 10^{9}+7 in one line.

Sample Input

3
1 2 1
2 3 1
3
1 2 1
1 3 2

Sample Output

16
24

Source

2018中国大学生程序设计竞赛 - 网络选拔赛

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章