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中國大學生程序設計競賽 - 網絡選拔賽

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