题目链接:
题意概括:
有 N 个点,被 N - 1 条边相连通。对于点 1 - N 的序列的全排列,求出第一个点到其余点的最短路之和,并求出所有情况的和。
数据范围:
不超过 10 组测试数据
题解分析:
由于是无环的联通图,这是一棵无根树。数据量很大,要是枚举点对来求的话,耗时太久
换一个思路,就是对于每条边,假如两条边的节点数分别为 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≤ ) .
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≤ ) .
Output
For each test case, print the answer module +7 in one line.
Sample Input
3
1 2 1
2 3 1
3
1 2 1
1 3 2
Sample Output
16
24