题解-Codeforces671D Roads in Yusland
Problem
Codeforces-671D
题意概要:给定一棵 \(n\) 点有根树与 \(m\) 条链,链有费用,保证链端点之间为祖先关系,问至少花费多少费用才能覆盖整棵树(\(n-1\) 条边)
\(n,m\leq 3\times 10^5\)
Solution
有一个线性规划的对偶式子(是从这篇里学习的):
\(\max\{c^Tx|Ax\leq b\}=\min\{b^Ty|A^Ty\geq c\}\)
(其中 \(x,y,b,c\) 为列向量,\(A\) 为一个矩阵)
其理解可以参照下面这个模型:
第一个式子中:工厂主有 \(n\) 个产品,其中 \(A\) 为这些产品所需原材料的数量,\(x\) 为产品生产数量,\(c\) 为生产一件产品的收益,\(b\) 为原材料数量
第二个式子中:喻同学有 \(m\) 种原材料,其中 \(A^T\) 上述矩阵的转置,\(b,c\) 同理,\(y\) 表示给原材料的定价
第一个式子中的现实意义:工厂主在使用现有原材料的情况下,生产产品所得最大收益
第二个式子中的现实意义:喻同学给工厂主的原材料定价,使得工厂主无论如何都无法获得任何收益,在此情况下尽量使得工厂主支出最少
由于工厂主要最大化自己的收益,而在喻同学的操作下,工厂主已经无法获益,要最大化自己收益(可能为负)只能尽量减少支出
由现实意义可以得出该式子,但严谨证明暂略
回到这题,由于求最小的花费不容易求,使用上述对偶关系进行转换:
原题套用第二个式子:
\(b^T\) : 每条链的费用
\(y\) : 每条链是否选择
\(A^T\) : 每条边是否被每条链覆盖
\(c\) : 每条边至少覆盖一次
求费用最小
对偶成第一个式子:
\(c^T\) : 每条边被覆盖一次
\(x\) : 给每条边构造的权值
\(A\) : 每条链是否覆盖每个点
\(b\) : 每条链的费用
求构造值之和最大
所以原题转化成:给定一棵树,要求给每条边构造一个权值,使得对于每条链而言,链上边权值之和不大于当前链的权值。由于原题保证链一定有祖先关系,可以左偏树贪心
Code
//Codeforces-671D
#include <bits/stdc++.h>
using namespace std;inline void read(int&x){char c11=getchar();x=0;while(!isdigit(c11))c11=getchar();while(isdigit(c11))x=x*10+c11-'0',c11=getchar();
}const int N = 301000;
struct Edge{int v,w,nxt;} a[N*3];
int head[N], Head[N];
int tag[N], cov[N];
int dep[N], len[N];
int rt[N], ls[N], rs[N];
int n,m,_,tot;long long Ans;inline void add(int x,int y,int z,int*arr){a[++_].v = y, a[_].w = z, a[_].nxt = arr[x], arr[x] = _;}struct node{int w, ps;}t[N];inline void put_tag(int x,int y) {t[x].w += y, tag[x] += y;}
inline void down_tag(int x){int&v = tag[x];if(!v) return ;if(ls[x]) put_tag(ls[x], v);if(rs[x]) put_tag(rs[x], v);v = 0;
}int merge(int x,int y){if(!x or !y) return x | y;down_tag(x), down_tag(y);if(t[x].w > t[y].w) swap(x,y);rs[x] = merge(rs[x], y);if(len[ls[x]] < len[rs[x]]) swap(ls[x], rs[x]);len[x] = len[rs[x]] + 1;return x;
}void dfs(int x,int las){for(int i=head[x];i;i=a[i].nxt)if(a[i].v != las){dep[a[i].v] = dep[x] + 1;dfs(a[i].v,x);rt[x] = merge(rt[x], rt[a[i].v]);cov[x] += cov[a[i].v];}if(x != 1 and !cov[x]) puts("-1"), exit(0);for(int i=Head[x];i;i=a[i].nxt){t[++tot] = (node) {a[i].w, a[i].v};rt[x] = merge(rt[x], tot);}while(rt[x] and dep[t[rt[x]].ps] >= dep[x]) rt[x] = merge(ls[rt[x]], rs[rt[x]]);Ans += t[rt[x]].w, put_tag(rt[x], -t[rt[x]].w);
}int main(){read(n), read(m);int x,y,z;for(int i=1;i<n;++i){read(x), read(y);add(x,y,0,head);add(y,x,0,head);}while(m--){read(x), read(y), read(z);++cov[x], --cov[y];add(x,y,z,Head);}dfs(1,0);printf("%lld\n",Ans);return 0;
}
转载于:https://www.cnblogs.com/penth/p/10596917.html
题解-Codeforces671D Roads in Yusland相关推荐
- 【CF671D】 Roads in Yusland(对偶问题,左偏树)
传送门 洛谷翻译 CodeForces Solution emmm,先引入一个对偶问题的概念 \(max(c^Tx|Ax \leq b)=min(b^Ty|A^Ty \ge c)\) 考虑这个式子的现 ...
- Codeforces 671D. Roads in Yusland(树形DP+线段树)
调了半天居然还能是线段树写错了,药丸 这题大概是类似一个树形DP的东西.设$dp[i]$为修完i这棵子树的最小代价,假设当前点为$x$,但是转移的时候我们不知道子节点到底有没有一条越过$x$的路.如果 ...
- CF671D Roads in Yusland
一道很玄妙的题= = 我们考虑先考虑DP 那么有$f[x]=min(c+\sum f[y])$ $f[x]$表示覆盖x的子树和x->fa[x]的所有边最小代价 我们枚举一条边c覆盖的x-> ...
- 省选前的计划(日更,然而你们天天吊打我)
还有17天就省选了,不能再颓废了! 总结篇(不定期更新) 网络流基本 计算几何基本 字符串入门+基础 斜率优化dp 日记篇(日更) 3.18 今天做了一些题目吧. 考试的题目也做了一道题目. 方格取数 ...
- 「tricks」整体DP
不太了解这个东西的具体定义是什么,总之应该是一个用数据结构维护 DP 状态的某几个维度的 trick 吧. 事实上你可以把这篇 post 理解为三个题的解集. 先直接来看 noi2020 - Dest ...
- codeforces泛做
codeforces div1的题目,一般是做B.C.D 有的A题觉得有价值也会做,死活不会的就跳了-- 364 B: Connecting Universities Problem: 一颗无根树上给 ...
- NOIP复健计划——动态规划
树形DP [POI2011] DYN-Dynamite 二分 K K K check(mid): 能否选出 m m m个点,使得 ∀ i 为关键点, M i n j i s s e l e c t e ...
- czl蒻蒟的OI之路13
XJOI奋斗群蒻蒟群群赛10 RANK排名6 T1Compote 已AC 题意 分析过程 给出题解 T2Decoding已AC 题意 分析过程 给出题解 T3Tram已AC 题意 分析过程 给出题解 ...
- Codeforces Round #352 div1 C D (智商+线段树)
Ultimate Weirdness of an Array 题意:给一个数列ai, f(i,j) 定义为除去i到j之间的数后最大gcd(ai, aj)的值, 求所有f(i,j)之和 #include ...
最新文章
- nginx try_files的理解
- [图]为C# Windows服务添加安装程序
- 相当于零负担的延时程序(转)
- 拒绝“魏则西悲剧”, 产品经理支招,根解百度医疗“莆田系”漏洞
- MySQL重置root用户密码的方法【亲测可用】
- java判断字符串有中文_JAVA入门之正则表达式判断字符串包含中文
- 换脸系列——整脸替换
- Oracle 12c 安装 Linuxx86_64
- ECCV 2020 GigaVision挑战赛“行人和车辆检测”和“多目标追踪”冠军方案解读
- Mac typora自定义编辑界面的配置
- vb调用存储过程的方法
- 颜色表大全 颜色中英文对照表
- 关于a标签下载文件变打开的解决方案
- springboot悠悠转二手网站毕业设计源码181134
- 负载均衡和Nginx
- web前端之幻灯片(二)--自动播放
- 八大方法改善皮肤黄气
- 基于微信小程序的音乐播放器设计
- C. Edgy Trees(并查集+细节)
- 《寒蝉鸣泣之时:携带版》游戏截图
热门文章
- JavaScript函数的arguments(2)
- rope 实用把一段区间的数字整体搬到序列中的一段的时候用
- bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居(切比雪夫距离+multiset贪心+并查集)
- 图像运动模糊原理及python实现
- C++中实现精度的控制和输出 showpoint<<或者fixed<<setprecision()用法
- 字符串的连接(复习)
- [Linux + 深度学习]Ubuntu18.04 深度学习环境配置
- [bug解决] Ubantu打不开Typora:typora error while loading shared libraries libXss.so.1
- Crackme017
- 一篇不大正经的关于数论的总结(未完