HDU - 6446 Tree and Permutation
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6446
本题是一个树上的问题——DFS。
一棵N个结点的树,其结点为1~N。树具有N-1条边,每一条边具有一个权值。
1~N具有N!个不同的排列,第i(1≤i≤N!)个排列记为P[i],第i个排列中的第j(1≤j≤N)个数记为P[i][j]。
对于第i个排列P[i],在树上沿最短路依次通过P[i][1]~P[i][N]。记最短路的权值和为S[i],求解:
$\sum_{i=1}^{N!} S_i \mod M$
考虑1~N间的两个不同的数u、v。在N!个排列中,v恰好为u的后继的排列数为(N-1)!。于是,若记u→v的最短路为D(u,v),则所求答案为:
$(N-1)!\:*\sum_{u\ne v}D(u,v)\mod M$
现在,考虑式:
$f(T)=\sum_{u<v}D(u,v)\cdots(*)$
接下来,考虑树的结点与边。无向树上的每一个结点都是树的割顶,每一条边都是树的桥。于是,树上的每一条边将树划分为两棵子树。考虑连接结点u、v的边:这条边将树划分为以结点u为根的子树、和以结点v为根的子树。设以结点u为根的子树的结点数为cnt[u],则以结点v为根的子树的结点数为cnt[v]=N-cnt[u]。
回到式(*)中,则边(u,v)对式子的贡献为$w(u,v)*cnt[u]*cnt[v]$。
考虑通过DFS预处理cnt[]:选取某一个结点作为根结点,通过DFS预处理以结点u为根的子树的结点数cnt[u]。之后,遍历树上的边:连接结点v与其父结点的边,其对式子的贡献为$w(p[v],v)*cnt[v]*(N-cnt[v])$。
考虑到双向,答案为$ans=2(N-1)!\:*f(T)\mod M$。
参考程序如下:
- #include <bits/stdc++.h>
- using namespace std;
- #define MAX_N 100005
- const int64_t mod = 1e9 + ;
- struct arrow
- {
- int to;
- int cost;
- arrow(int to = , int cost = ) : to(to), cost(cost) {}
- };
- int64_t fact[MAX_N];
- void init(void)
- {
- fact[] = ;
- for (int i = ; i < MAX_N; i++) fact[i] = fact[i - ] * i % mod;
- }
- int n;
- vector<arrow> adj[MAX_N];
- int64_t ans;
- int cnt[MAX_N];
- void dfs_cnt(int u, int p)
- {
- cnt[u] = ;
- for (int i = ; i < adj[u].size(); i++) {
- int v = adj[u][i].to;
- if (v == p) continue;
- dfs_cnt(v, u);
- cnt[u] += cnt[v];
- }
- }
- void dfs_calc(int u, int p)
- {
- for (int i = ; i < adj[u].size(); i++) {
- int v = adj[u][i].to;
- int w = adj[u][i].cost;
- if (v == p) continue;
- int64_t cur = 1ll * cnt[v] * (n - cnt[v]);
- ans += cur * w % mod;
- ans %= mod;
- dfs_calc(v, u);
- }
- }
- int main(void)
- {
- ios::sync_with_stdio(false);
- init();
- while (cin >> n) {
- memset(cnt, , sizeof(cnt));
- for (int i = ; i < n; i++) {
- int u, v, w;
- cin >> u >> v >> w;
- adj[u].push_back(arrow(v, w));
- adj[v].push_back(arrow(u, w));
- }
- ans = ;
- dfs_cnt(, -);
- dfs_calc(, -);
- cout << 2ll * ans % mod * fact[n - ] % mod << endl;
- for (int i = ; i <= n; i++) adj[i].clear();
- }
- return ;
- }
HDU - 6446 Tree and Permutation的更多相关文章
- (1009) HDU 6446 Tree and Permutation(规律+树上各个点的距离和)
题意: 给一棵N个点的树,对应于一个长为N的全排列,对于排列的每个相邻数字a和b,他们的贡献是对应树上顶点a和b的路径长,求所有排列的贡献和. 分析: 经过简单的分析可以得知,全部的贡献其实相当与(这 ...
- HDU 6446 Tree and Permutation(赛后补题)
>>传送门<< 分析:这个题是结束之后和老师他们讨论出来的,很神奇:刚写的时候一直没有注意到这个是一个树这个条件:和老师讨论出来的思路是,任意两个结点出现的次数是(n-1)!, ...
- Tree and Permutation (HDU 6446) 题解
// 昨天打了一场网络赛,表现特别不好,当然题目难度确实影响了发挥,但还是说明自己太菜了,以后还要多多刷题. 2018 CCPC 网络赛 I - Tree and Permutation 简单说明一下 ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 hdu Tree and Permutation 找规律+求任意两点的最短路
Tree and Permutation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- HDU 5868 Different Circle Permutation(burnside 引理)
HDU 5868 Different Circle Permutation(burnside 引理) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=586 ...
- hdu 5225 Tom and permutation(回溯)
题目链接:hdu 5225 Tom and permutation #include <cstdio> #include <cstring> #include <algo ...
- hdu 5909 Tree Cutting [树形DP fwt]
hdu 5909 Tree Cutting 题意:一颗无根树,每个点有权值,连通子树的权值为异或和,求异或和为[0,m)的方案数 \(f[i][j]\)表示子树i中经过i的连通子树异或和为j的方案数 ...
- HDU6446 Tree and Permutation(树上DP)
传送门:点我 Tree and Permutation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (J ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1009 - Tree and Permutation 【dfs+树上两点距离和】
Tree and Permutation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
随机推荐
- Tool:Adobe Photoshop
ylbtech-Tool-Adobe:Adobe Photoshop 1.返回顶部 1. Adobe Photoshop,简称“PS”,是由Adobe Systems开发和发行的图像处理软件. Pho ...
- Ubuntu搭建Eclipse+JDK+SDK的Android (转载)
转自:http://blog.csdn.net/ithomer/article/details/6960989 今晚重装Ubuntu系统,重新安装了一套eclipse+jdk+SDK的Android开 ...
- bootstrap的modal弹窗,在多层窗口关闭时只会关闭自窗口,不再关闭父窗口
bootstrap多层modal弹窗时.当子窗口关闭时,所有父窗口一起关闭. 原因是bootstrap在窗口关闭事件委托时,委托给所有窗口. 如源码: this.$element.on('click. ...
- bzoj 1645: [Usaco2007 Open]City Horizon 城市地平线【线段树+hash】
bzoj题面什么鬼啊-- 题目大意:有一个初始值均为0的数列,n次操作,每次将数列(ai,bi-1)这个区间中的数与ci取max,问n次后元素和 离散化,然后建立线段树,每次修改在区间上打max标记即 ...
- Web前端汇总
http://www.cnblogs.com/bigboyLin/p/5272902.html HTML/CSS部分 1.什么是盒子模型? 在网页中,一个元素占有空间的大小由几个部分构成,其中包括 ...
- 设计基于HTML5的APP登录功能及安全调用接口的方式
转自:http://blog.csdn.net/linlzk/article/details/45536065 最近发现群内大伙对用Hbuilder做的APP怎么做登录功能以及维护登录状态非常困惑,而 ...
- 安装Kali里的应用程序或软件包
安装Kali里的应用程序或软件包 安装额外的软件是apt-get命令最基本的功能了,命令非常简单易懂.安装软件包的语法如下: apt-get install 软件包名 比如,安装图像编辑软件gimp, ...
- Kafka~消费的有效期
消息的过期时间 我们在使用Kafka存储消息时,如果已经消费过了,再永久存储是一种资源的浪费,所有,kafka为我们提供了消息文件的过期策略,可以通过配置server.properies来实现# vi ...
- 【工具】前端Photoshop
前端photoshop最常见问题: 字体单位换成像素:按下ctrl+k调出首选项,选择单位与标尺,在里面把文字单位由点改为像素就行了.不过要注意的是,点是很多软件里面文字的默认单位.像素是虚拟单位,如 ...
- Linux学习笔记之Linux命令
1. blkid 查看当前系统中所有已挂载文件系统的类型