[题解] 树(tree)
题目大意
给定一颗 \(N\) 个点的有根树,其中 \(1\) 是树根,除了 \(1\) 以外的其他点 \(u\) 有唯一的父亲 \(Father_u\)。同时,给定 \(M\) 条路径,第 \(i\) 条路径是 \((s_i,t_i)\),保证 \(s_i\) 是 \(t_i\) 的祖先。你可以任意选择若干条路径。如果第 \(i\) 条路径被选择,那么你可以得到 \(V_i\) 的收益,这里保证 \(V_i\) 是非负的。
同时,对于每个不是 \(1\) 的点 \(u\),考虑其连接它的父亲 \(Father_u\) 的边,如果有 \(x\) 条覆盖了它且被选择的路径,需要花费代价 \(A_u\times x^2+B_u\times x\),这里也保证 \(A_u\) 和 \(B_u\) 是非负的。代价的含义就是收益要减去这么多,相当于负的收益。
你需要求出在以上条件下你的最大收益。
数据范围:\(1\leq N,M\leq 150\),\(\forall2\leq u\leq N,0\leq A_u \leq 100,0\leq B_u \leq 10000\),\(\forall 1\leq i \leq M,0\leq V_i \leq 10^6\),并保证 \(s_i\) 总是 \(t_i\) 的祖先。
时间限制:1000ms
空间限制:1024MB
解题思路
题解直接给出了费用流的建图方案,然后证明正确性,这里还是想想要如何想到使用费用流。
数据范围只是一个小点,不过确实可以考虑按照数据范围整理一个常用算法表。
关键点应该在于费用是二次的,像这种似乎是很不好处理的,如果是全局二次的话,大概还可以二分或者枚举一下次数,但是这是每条边都是一个二次费用,所以目前所知道的算法里,只有费用流按每次连边能实现这一点,因为对于费用的贪心可以保证按照需要的顺序流过这些流。
于是就考虑建图。费用流有一种常见的做法是先考虑全部都选择,然后计算需要减去的费用, 那么要么是减去 \(v_i\) 直接不选,要么是减去路上的费用,按照这个思路建图就好了。
#include <bits/stdc++.h>
using namespace std;
const int N(155), E(N * (N + 3)), INF(1e9);
int n, m, fa[N], a[N], b[N], s[N], t[N], v[N];
int ans;
int cnt = 1, head[N];
int S, T, dcnt, dis[N], flo[N], pre[N], inq[N];
struct edge{ int nx, to, v, f; } e[E << 1];
inline void read(int &x){
x = 0; int f = 1, c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)) x = x * 10 + c - 48, c = getchar();
x *= f;
}
inline void input(){
read(n), read(m);
for(int i(2); i <= n; ++i) read(fa[i]), read(a[i]), read(b[i]);
for(int i(1); i <= m; ++i) read(s[i]), read(t[i]), read(v[i]);
}
inline void add(int u, int v, int w, int f){
e[++cnt] = {head[u], v, w, f}, head[u] = cnt;
e[++cnt] = {head[v], u, -w, 0}, head[v] = cnt;
}
inline void prep(){
S = n + 1, T = 1, dcnt = n + 1;
for(int i(2); i <= n; ++i)
for(int j(1); j <= m; ++j) add(i, fa[i], (j * 2 - 1) * a[i] + b[i], 1);
for(int i(1); i <= m; ++i)
add(S, t[i], 0, 1), add(s[i], T, 0, 1), add(t[i], s[i], v[i], 1), ans += v[i];
}
bool spfa(){
static queue <int> Q;
for(int i(1); i <= dcnt; ++i) dis[i] = INF;
dis[S] = 0, flo[S] = INF, Q.push(S), inq[S] = 1;
while(!Q.empty()){
int x = Q.front(); Q.pop(), inq[x] = 0;
for(int i(head[x]); i; i = e[i].nx){
int y = e[i].to;
if(dis[y] > dis[x] + e[i].v && e[i].f){
dis[y] = dis[x] + e[i].v;
flo[y] = min(flo[x], e[i].f);
pre[y] = i;
if(!inq[y]) Q.push(y), inq[y] = 1;
}
}
}
return dis[T] != INF;
}
inline void work(){
int mf = 0, mc = 0;
while(spfa()){
mf += flo[T], mc += flo[T] * dis[T];
int now = T;
while(now){
now = pre[now];
e[now].f -= flo[T], e[now ^ 1].f += flo[T];
now = e[now ^ 1].to;
}
}
ans -= mc;
}
inline void output(){ printf("%d\n", ans); }
int main(){
freopen("tree.in", "r", stdin);
freopen("tree.out", "w", stdout);
input();
prep();
work();
output();
return 0;
}
[题解] 树(tree)的更多相关文章
- 树(tree)
树(tree)[题目描述]从前在森林里面有一棵很大的树,树上住着很多小动物.树上有
- JS--插件: 树Tree 开发与实现
日常在Web项目开发时,经常会碰到树形架构数据的显示,从数据库中获取数据,并且显示成树形.为了方便,我们可以写一个javascript的一个跨浏览器树控件,后续可以重复使用.本节分享一个自己开发的JS ...
- POJ1741:Tree——题解+树分治简要讲解
http://poj.org/problem?id=1741 题目大意:给一棵树,求点对间距离<=k的个数. ———————————————————— 以这道题为例记录一下对于树分治的理解. 树 ...
- [LeetCode 题解]: Symmetric Tree
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given a ...
- 竞赛题解 - Broken Tree(CF-758E)
Broken Tree(CF-758E) - 竞赛题解 贪心复习~(好像暴露了什么算法--) 标签:贪心 / DFS / Codeforces 『题意』 给出一棵以1为根的树,每条边有两个值:p-强度 ...
- 6359. 【NOIP2019模拟2019.9.15】小ω的树(tree)(定期重构)
题目描述 题解 qy的毒瘤题 CSP搞这种码农题当场手撕出题人 先按照边权从大到小建重构树,然后40%暴力修改+查找即可 100%可以定期重构+平衡规划,每次把B个询问拉出来建虚树,在虚树上暴力维护每 ...
- leetcode题解:Binary Tree Postorder Traversal (二叉树的后序遍历)
题目: Given a binary tree, return the postorder traversal of its nodes' values. For example:Given bina ...
- leetcode 题解:Binary Tree Preorder Traversal (二叉树的先序遍历)
题目: Given a binary tree, return the preorder traversal of its nodes' values. For example:Given binar ...
- 轻量级jquery框架之--树(tree)
前言 在常用的UI组件中,树形组件与数据列表组件可以说是构成一个管理平台基本的两大数据核心组件.树形组件用于系统菜单,数据列表用于数据表现,两者配合即可完成一个简单的数据系统.要实现一个支持复选.工具 ...
随机推荐
- maven下载出现unknown文件夹
问题场景 maven下载配置完成后,发现如上图代码包下载失败,本地maven库中出现unknown文件夹,也就是说,maven无法定位下载到上面的代码包. 解决过程 仔细观察发现,所有下载失败的代码包 ...
- jedis 和 redisson 有哪些区别?
Jedis 和 Redisson 都是Java中对Redis操作的封装.Jedis 只是简单的封装了 Redis 的API库,可以看作是Redis客户端,它的方法和Redis 的命令很类似.Redis ...
- (stm32学习总结)—GPIO位带操作
本章参考资料:<STM32F10X-中文参考手册>存储器和总线构架章节.GPIO 章节,<CM3 权威指南 CnR2>存储器系统章节. 位带简介 位操作就是可以单独的对一个比特 ...
- 汽车中的低速can和高速can的区别
转自:https://zhuanlan.zhihu.com/p/33212308
- Web最佳实践阅读总结(1)
介绍 最近开始刷一些书和题,此系列是介绍在读Web最佳实践的一些收获和体会. web前端发展现状 存在问题: 代码组织混乱 代码格式的问题突出 页面布局随意 网站整体性能差,没有意识到应用诸如缓存,动 ...
- 关于个人开源项目(vue app)的一些总结
关于个人开源项目(vue app)的一些总结 项目地址 https://github.com/BYChoo/record 项目简介 此项目名叫:Record.是以Vue全家桶(vue,vue-rout ...
- 一块小饼干(Cookie)的故事-上篇
cookie 如果非要用汉语理解的话应该是 一段小型文本文件,由网景的创始人之一的卢 蒙特利在93年发明. 上篇是熟悉一下注册的大致流程,下篇熟悉登录流程以及真正的Cookie 实现基本的注册功能 我 ...
- java基础-多线程 等待唤醒机制
/** * @param args * 等待唤醒机制 */ public static void main(String[] args) { final Printer p = new ...
- Python使用递归绘制谢尔宾斯基三角形
谢尔宾斯基三角形使用了三路递归算法,从一个大三角形开始,通过连接每一个边的中点,将大三角型分为四个三角形,然后忽略中间的三角形,依次对其余三个三角形执行上述操作. 运行效果: 源代码: 1 impor ...
- golang对接阿里云私有Bucket上传图片、授权访问图片
golang对接阿里云私有Bucket上传图片.授权访问图片 1.为什么要设置私有bucket 公共读写:互联网上任何用户都可以对该 Bucket 内的文件进行访问,并且向该 Bucket 写入数据. ...