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 ...
随机推荐
- RAR去除广告
现在注册已经不能去掉广告了,给你一个100%有效的办法(##此教程已更新,最新的winrar5.5同样适用,但是多了一个步骤) 电脑桌面新建一个txt文件,重命名为“rarreg.key” 2. 将. ...
- bzoj 4326: NOIP2015 运输计划【树链剖分+二分+树上差分】
常数巨大,lg上开o2才能A 首先预处理出运输计划的长度len和lca,然后二分一个长度w,对于长度大于w的运输计划,在树上差分(d[u]+1,d[v]+1,d[lca]-2),然后dfs,找出所有覆 ...
- bzoj 2101: [Usaco2010 Dec]Treasure Chest 藏宝箱【区间dp】
就是区间dp啦f[i][j]表示以i开头的长为j+1的一段的答案,转移是f[i][j]=s[i+l]-s[i-1]+min(f[i][j-1],f[i+1][j-1]),初始是f[i][1]=a[i] ...
- python/shell脚本报异常^M: bad interpreter: No such file or directory
问题:在Windows写了一python脚本,上传Linux服务器执行,报异常*****^M: bad interpreter: No such file or directory 原因:window ...
- [BZOJ1331]魔板
Description 在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板.这是一张有8个大小相同的格子的魔板: 1 2 3 4 8 7 6 5 我们知道魔板的每一个方格都有一种颜色.这8 ...
- DFS POJ 1321 棋盘问题
题目传送门 /* DFS:因为一行或一列都只放一个,可以枚举从哪一行开始放,DFS放棋子,同一列只能有一个 */ #include <cstdio> #include <algori ...
- Android 性能优化(7)网络优化( 3) Optimizing User-Initiated Network Use
Optimizing User-Initiated Network Use This lesson teaches you to Pre-fetch Network Data Check for Co ...
- JavaScript01天学习笔记分享
01知识点 JavaScript 代码运行在浏览器(后缀名.js) 和java完全不同的东西,只是名称类型而已 src 引用脚本 <Script></Script> ale ...
- poj3411 Paid Roads
思路: 搜索.注意点和边都有可能经过多次. 实现: #include <iostream> #include <cstdio> #include <vector> ...
- WordPress个性页面制作教程
写在前面的话: 有很多WordPress小伙伴想制作不同风格的页面来满足自己的个性需求 但是大多数模板提供的页面模板非常有限,该如何手动制作属于自己风格的模板页呢? 其实,正如以上所说的,每个人都想拥 ...