题解-Codeforces671D Roads in Yusland
Problem
题意概要:给定一棵 \(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
/*
Problem Source : cf-671D
Author : oier_hzy
Time : Nov 19 2019
*/
#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]) {
down_tag(rt[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;
}
题解-Codeforces671D Roads in Yusland的更多相关文章
- [Codeforces671D]Roads in Yusland
[Codeforces671D]Roads in Yusland Tags:题解 题意 luogu 给定以1为根的一棵树,有\(m\)条直上直下的有代价的链,求选一些链把所有边覆盖的最小代价.若无解输 ...
- Codeforces 671 D. Roads in Yusland
题目描述 Mayor of Yusland just won the lottery and decided to spent money on something good for town. Fo ...
- 【CF671D】Roads in Yusland(贪心,左偏树)
[CF671D]Roads in Yusland(贪心,左偏树) 题面 洛谷 CF 题解 无解的情况随便怎么搞搞提前处理掉. 通过严密(大雾)地推导后,发现问题可以转化成这个问题: 给定一棵树,每条边 ...
- 【CF617D】Roads in Yusland
[CF617D]Roads in Yusland 题面 蒯的洛谷的 题解 我们现在已经转化好了题目了,戳这里 那么我们考虑怎么求这个东西,我们先判断一下是否所有的边都能被覆盖,不行的话输出\(-1\) ...
- 【CodeForces】671 D. Roads in Yusland
[题目]D. Roads in Yusland [题意]给定n个点的树,m条从下往上的链,每条链代价ci,求最少代价使得链覆盖所有边.n,m<=3*10^5,ci<=10^9,time=4 ...
- codesforces 671D Roads in Yusland
Mayor of Yusland just won the lottery and decided to spent money on something good for town. For exa ...
- 题解-CodeForces835F Roads in the Kingdom
Problem CodeForces-835F 题意:求基环树删去环上任意一边后直径最小值,直径定义为所有点对最近距离的最大值 Solution 首先明确删去环上一点是不会影响树内直径的,所以应当先把 ...
- Codeforces 671D Roads in Yusland [树形DP,线段树合并]
洛谷 Codeforces 这是一个非正解,被正解暴踩,但它还是过了. 思路 首先很容易想到DP. 设\(dp_{x,i}\)表示\(x\)子树全部被覆盖,而且向上恰好延伸到\(dep=i\)的位置, ...
- codeforces 671D Roads in Yusland & hdu 5293 Tree chain problem
dp dp优化 dfs序 线段树 算是一个套路.可以处理在树上取链的问题.
随机推荐
- 一入OI深似海 3 —— 纪念我最后一次PJ(上)
其实在比赛前一天中午上车前, 我还在机房打 I wanna, 感觉就是去杭州旅游的. 诶,还真是这样! 我和jwj在绍兴服务区买了金拱门, 拎着吃的回到车上的时候, 迎面而来羡慕的小眼神. 下午很早就 ...
- 【HTML】行内-块级-行块级
行内元素 相邻元素可以在一行显示直到一行排不下才进行换行. 不可设置宽高,宽度随内容变化. padding和margin的设置中,水平方向(padding-left...)有效果,垂直方向无效果. 块 ...
- application.properties
#MySQLspring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://lo ...
- 京东iPad新品开售销量环比增22倍
一年一度万众期待的 Apple 春季发布会终于在今天凌晨揭晓,Apple 新推的 Apple News.Apple Card.Apple Arcade 和 Apple TV+ 四大软件服务惊喜不断,随 ...
- UOJ#449. 【集训队作业2018】喂鸽子(期望dp)
题意 有 \(n\) 只鸽子,每只鸽子需要 \(k\) 粒玉米才能喂饱.问每次随意喂给 \(n\) 个鸽子中的一个,期望多久所有鸽子都被喂饱. 对于 \(998244353\) 取模. 数据范围 \( ...
- P1282 多米诺骨牌 (背包变形问题)
题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...
- 关于SDK_JDK_JRE_JVM的关系
SDK JDK JRE JVM 四者的关系 一:SDK与JDK的关系(可以认为jdk只是sdk的一种子集) SDK是Software Development Kit的缩写,中文意思是“软件开发工具包” ...
- spring IOC与AOP
Spring IOC容器 spring IOC 容器有两种,分别是 BeanFactory 容器和 ApplicationContext 容器. BeanFactory如下: /*第一步,利用Clas ...
- (模拟) codeVs1160 蛇形矩阵
题目描述 Description 小明玩一个数字游戏,取个n行n列数字矩阵(其中n为不超过100的奇数),数字的填补方法为:在矩阵中心从1开始以逆时针方向绕行,逐圈扩大,直到n行n列填满数字,请输出该 ...
- Apache Hadoop 2.9.2 的集群管理之服役和退役
Apache Hadoop 2.9.2 的集群管理之服役和退役 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 随着公司业务的发展,客户量越来越多,产生的日志自然也就越来越大来,可能 ...