2018中国大学生程序设计竞赛 - 网络选拔赛 1009 - Tree and Permutation 【dfs+树上两点距离和】
Tree and Permutation
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 619 Accepted Submission(s): 214
Problem Description
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
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
大概题意:
给一棵N个节点的树, 求按N个节点全排列的顺序走一遍这棵树所得的路径贡献和。
解题思路:
对于所有按照全排列走过的路径,打表会发现,每两点之间的距离都出现了 (N-1)!次,所以我们只需要求出 所有两点之间的距离之和就可以解得最后的答案了。
也就是说我们只需要求出 ∑dis(i, j) 最后 ∑dis(i, j) * (N-1)! 就是答案了。
∑dis(i, j) 的求法:
我们可以根据当前节点 root 和 它的父节点 fa 的边 v 把一棵树分成两部分, 一部分是 以 fa 为根节点的子树,一部分是以 root 为根节点的子树(即除去这课子树是另一部分)。
如果我们已经预先知道了 fa 到 这棵树每个节点的距离和 sum_dis[ fa ], 以及以 root 为根节点的子树的大小t_size[ root ] ,那么 节点 root 到树上其他节点的距离和我们可以通过 sum_dis[ fa ]转化而来;
因为sum_dis[fa] 减去 v 对上面所分成的树的两部分的影响剩下的就是sum_dis[root] 即sum_dis[root] = sum_dis[fa] - (N-t_size[root])*v - t_size[root]*v ;
因此,我们第一步dfs把 1 到各个节点的距离和求出来,第二步通过对 1 的距离和转换 把其他节点的距离和求出来,最后所有距离和求和得出答案。
AC code:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#define ll long long int
#define mod 1000000007
#define INF 0x3f3f3f3f
using namespace std; const int MAXN = 1e5+;
struct date{
int v, next, len;
}node[MAXN<<];
ll sum_dis[MAXN];
int t_size[MAXN];
int head[MAXN], cnt;
int N; void init()
{
memset(head, -, sizeof(head));
cnt = ;
memset(sum_dis, , sizeof(sum_dis));
memset(t_size, , sizeof(t_size));
}
void add(int from, int to, int weight)
{
node[++cnt].next = head[from];
head[from] = cnt;
node[cnt].v = to;
node[cnt].len = weight;
}
void dfs(int root, int fa, ll dis)
{
sum_dis[] = (sum_dis[]%mod+dis%mod)%mod;
t_size[root] = ;
for(int x = head[root]; x != -; x =node[x].next)
{
if(node[x].v != fa)
{
dfs(node[x].v, root, (dis+node[x].len)%mod);
t_size[root]+=t_size[node[x].v];
}
}
}
void trans(int root, int fa)
{
int vv;
for(int i = head[root]; i != -; i= node[i].next)
{
vv = node[i].v;
if(node[i].v != fa){
sum_dis[vv] = (sum_dis[root]%mod+((1ll*(N-*t_size[vv])*node[i].len)%mod)%mod)%mod;
if(sum_dis[vv] < ) sum_dis[vv] += mod;
trans(vv, root);
}
}
}
int main()
{
int f, t, w;
while(~scanf("%d", &N))
{
init();
for(int i = ; i < N; i++)
{
scanf("%d%d%d", &f, &t, &w);
add(f, t, w);
add(t, f, w);
}
dfs(, , );
trans(, );
ll P = , ans = ;
for(int i = ; i < N; i++)
P = 1ll*P*i%mod;
for(int i = ; i <= N; i++)
ans = (ans + sum_dis[i])%mod;
ans = ans*P%mod;
printf("%lld\n", ans);
}
return ;
}
2018中国大学生程序设计竞赛 - 网络选拔赛 1009 - Tree and Permutation 【dfs+树上两点距离和】的更多相关文章
- 2018中国大学生程序设计竞赛 - 网络选拔赛 hdu Tree and Permutation 找规律+求任意两点的最短路
Tree and Permutation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1001 - Buy and Resell 【优先队列维护最小堆+贪心】
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6438 Buy and Resell Time Limit: 2000/1000 MS (Java/O ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...
- HDU - 6440 Dream 2018中国大学生程序设计竞赛 - 网络选拔赛
给定的\(p\)是素数,要求给定一个加法运算表和乘法运算表,使\((m+n)^p = m^p +n^p(0 \leq m,n < p)\). 因为给定的p是素数,根据费马小定理得 \((m+n) ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 Dream hdu6440 Dream 给出一个(流氓)构造法
http://acm.hdu.edu.cn/showproblem.php?pid=6440 题意:让你重新定义任意一对数的乘法和加法结果(输出乘法口诀表和加法口诀表),使得m^p+n^p==(m+n ...
- hdu6444 2018中国大学生程序设计竞赛 - 网络选拔赛 1007 Neko's loop
Neko's loop Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total S ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 Solution
A - Buy and Resell 题意:给出n个交易点,每次能够选择买或者卖,求获得最大利润 思路:维护两个优先队列,一个是卖,一个是替换,当价格差相同时,优先替换,因为次数要最少 #includ ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 4 - Find Integer 【费马大定理+构造勾股数】
Find Integer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Tota ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 hdu 6440 Dream 模拟
Dream Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Subm ...
随机推荐
- sql常用格式化函数及字符串函数
一.常用格式化函数 1.日期转字符串 select to_char(current_timestamp, 'YYYY-MM-DD HH24:MI:SS') YYYY:年份 MM:月份号(01-12) ...
- org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [null]; nested exception is org.hibernate.
今天报了这个异常,这是页面报的 org.springframework.dao.DataIntegrityViolationException: could not execute statement ...
- Markdown简易使用
Markdown 笔记 标题 1.一级标题 2.二级标题 3.三级标题 列表 这是 一个 无序列表 这是 一个 有序列表 引用 这是一条引用 图片与链接 图片 链接 Baidu 粗体与斜体 粗体 斜体 ...
- 数据库和AI的一次火花
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由宗文 发表于云+社区专栏 | 导语 通过历史数据,基于时间序列来预测未来. 我们生活中很多数据是有时间维度的.比如说天气或者股票价格. ...
- nagios监控远程端口
check_port 位置:/usr/local/nagios/libexec/ 代码(新建可执行文件) #!/bin/sh /usr/local/nagios/libexec/check_tcp - ...
- bzoj 5084: hashit
Description 你有一个字符串S,一开始为空串,要求支持两种操作 在S后面加入字母C 删除S最后一个字母 问每次操作后S有多少个两两不同的连续子串 Solution 先忽略删除操作,建出最终的 ...
- Oracle 过程中变量赋值
create or replace function get_sal1(id employees.employee_id%type) return number is sal employees.sa ...
- sublime开启vi编辑器功能,与vi常用快捷键
sublime开启vi编辑器 install package -> vintageES 设置里面 ignored_packages 里面的vintage去掉 VI命令 游标控制 h 游标向左移 ...
- Linux 网络(连接)相关参数作用
参考: [1] http://bbs.chinaunix.net/thread-2318039-1-1.html Backlog net.core.netdev_max_backlog = 1000 ...
- input placeholder 在chrome 浏览器自动填充时,背景色覆盖原有背景图片问题。
user-block-name, .user-block-pwd { margin-bottom: 10%; text-align: center; position: relative; } .us ...