2019沈阳网赛树形dp
时间:2019-09-16
本文章向大家介绍2019沈阳网赛树形dp,主要包括2019沈阳网赛树形dp使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
https://nanti.jisuanke.com/t/41403
2019沈阳网络赛D题
树形dp。一棵树,求任意两个点的距离之和。u-v和v-u算两次。两点之间的距离分为三类,模3等于0,1,2三类,最后输出这三类的总和。
第一种方法。直接累加。遍历到一个点的时候。先计算答案。答案加上所有已经遍历过得点到他的距离之和。同时该点也要加上这个值,同时要加上数量。每次先搜到底统计往下遍历的值,然后回溯的时候统计
回溯的值。因为每次只计算了之前的点到他的距离之和,所以最后的结果要乘以2,因为u-v与v-u算两次。
每次加的时候先计算当前点前一个点到他的距离,及0+该边的边权。然后在按0,1,2来累加,如果为零表示没有,就不累加。
#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e4 + 5; const int mod = 1e9 + 7; typedef pair<int, ll> pii; int n; vector<pii> g[N]; ll ans[4];//结果数组 struct Node { ll valup[4];//递归回溯的时候 ll valdown[4];//递归往下的时候 ll cntdown[4], cntup[4];//递归往下与回溯的点数量。 } node[N]; void dfs(int u, int f) { int len = g[u].size(); for(int i = 0; i < len; i++) { int v = g[u][i].first; ll w = g[u][i].second; if(v == f) continue; node[v].valdown[w%3] = (node[v].valdown[w%3] + w) % mod; node[v].cntdown[w%3] = (node[v].cntdown[w%3] + 1) % mod; ans[w%3] = (ans[w%3] + w) % mod; for(int j = 0; j < 3; j++) { ll ww = (node[u].valdown[j] + node[u].valup[j]) % mod; ll cnt = (node[u].cntdown[j] + node[u].cntup[j]) % mod; if(ww == 0) continue; ll mo = (j + w) % 3; node[v].valdown[mo] = (node[v].valdown[mo] + ww) % mod; node[v].valdown[mo] = (node[v].valdown[mo] + w * cnt) % mod; node[v].cntdown[mo] = (node[v].cntdown[mo] + cnt) % mod; ans[mo] = (ans[mo] + ww) % mod; ans[mo] = (ans[mo] + w * cnt) % mod; } dfs(v, u); node[u].valup[w%3] = (node[u].valup[w%3] + w) % mod; node[u].cntup[w%3] = (node[u].cntup[w%3] + 1) % mod; for(int j = 0; j < 3; j++) { ll ww = node[v].valup[j]; ll cnt = node[v].cntup[j]; if(ww == 0) continue; ll mo = (j + w) % 3; node[u].valup[mo] = (node[u].valup[mo] + ww) % mod; node[u].valup[mo] = (node[u].valup[mo] + w * cnt) % mod; node[u].cntup[mo] = (node[u].cntup[mo] + cnt) % mod; } } } int main() { while(~scanf("%d", &n)) { int u, v; ll w; ans[0] = ans[1] = ans[2] = 0; for(int i = 0; i < n; i++) { g[i].clear(); for(int j = 0; j < 4; j++) node[i].valup[j] = node[i].valdown[j] = node[i].cntdown[j] = node[i].cntup[j] = 0; } for(int i = 1; i < n; i++) { scanf("%d%d%lld", &u, &v, &w); g[u].push_back(pii(v, w)); g[v].push_back(pii(u, w)); } dfs(0, -1); for(int i = 0; i < 3; i++) { printf("%lld%c", (ans[i] * 2) % mod, i == 2 ? '\n' : ' '); } } return 0; }
原文地址:https://www.cnblogs.com/downrainsun/p/11528832.html
- kvm虚拟化管理平台WebVirtMgr部署-完整记录(1)
- objective-C中如何判断一个类中有没有定义某个方法
- Steve Boswell:智能口罩让PM2.5滚蛋
- kvm虚拟化管理平台WebVirtMgr部署-完整记录(2)
- objective-C中的扩展方法与partial class
- 仿优酷Android客户端图片左右滑动(自动滑动)
- objective-C: NSString应该用initWithFormat? 还是 stringWithFormat?
- objective-C 的内存管理之-实例分析
- Tim Berners-Lee:网络的自由和开放
- android防止内存溢出浅析
- objective-C 的内存管理之-自动释放池(autorelease pool)
- objective-C 的内存管理之-引用计数
- CompoundButton.OnCheckedChangeListener与RadioGroup.OnCheckedChangeListener冲突
- Liora Rosin & Golan Levi:在北京驾车看洛杉矶的落日
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- linux中使用boost.python调用c++动态库的方法
- linux下pip的安装步骤及使用详解
- CentOS7安装配置 Redis的方法步骤
- Linux下Oracle如何导入导出dmp文件详解
- Linux中samba服务器的搭建教程
- linux环境搭建图数据库neo4j的讲解
- Linux编程之ICMP洪水攻击
- linux搭建squid代理服务器的完整步骤
- 使用wget递归镜像网站
- 整理Linux中字符串的相关操作技巧
- Ubuntu 16.04下无法安装.deb的解决方法
- 关于linux中系统输入输出的管理详解
- Linux下IP设置脚本的实例及遇到问题解决办法
- Linux与Windows文件互传(VMWare)
- 如何测试Linux下tcp最大连接数限制详解