[Codeforces671D]Roads in Yusland
[Codeforces671D]Roads in Yusland
Tags:题解
题意
luogu
给定以1为根的一棵树,有\(m\)条直上直下的有代价的链,求选一些链把所有边覆盖的最小代价。若无解输出-1
\(n\le 3*10^5\)
题解
这题有一些DP做法,这里不再赘述了。
首先你得知道线性规划的对偶。
式子是这样的\(max\{c^Tx|Ax\le b\}=min\{b^Ty|A^Ty\ge c\}\)
强行往上面套(右式):
- \(c\)为全1列向量,长度为\(m\)
- \(y\)为01列向量,长度为\(m\),表示每条链选或不选
- \(A^T\)为长\(n-1\)、宽\(m\)的01矩阵,\(A[i][j]\)表示\(i\)这条边在不在第\(j\)条链中
- \(b^T\)为长为\(m\)的行向量,表示选每条链的代价
所以现在的问题就是要构造一个\(x\)使得左式最大。
那我们寻找左式的实际意义:给每条边标记一个权值\(x\),使得每条链上的边的权值和不超过其代价。
感觉完全不是一个问题了对吧,但是确实他们答案相同。
为方便表述,这条边标记权值\(x\)记为这条边选了\(x\)次。
然后这是一个较为显然的贪心,从深到浅能选则选,用可并堆维护当前点到父亲这条边能选的最多次数。
代码
#include<iostream>
#include<vector>
#define pb push_back
#define lc t[x].ch[0]
#define rc t[x].ch[1]
using namespace std;
const int N=3e5+10;
int n,m,cf[N],rt[N],dep[N],nod;
long long Ans;
vector<int> E[N],St[N];
struct mmp{int x,y,c;}A[N];
struct Heap{int ch[2],val,id,dis,tag;}t[N];
void Put(int x,int k) {t[x].tag+=k;t[x].val+=k;}
void pushdown(int x) {int &v=t[x].tag;if(v) Put(lc,v),Put(rc,v),v=0;}
int Merge(int x,int y)
{
if(!x||!y) return x+y;
pushdown(x);pushdown(y);
if(t[x].val>t[y].val) swap(x,y);
rc=Merge(rc,y);
if(t[lc].dis<t[rc].dis) swap(lc,rc);
t[x].dis=t[lc].dis+1;
return x;
}
int Del(int x) {return Merge(lc,rc);}
void dfs(int x,int fr)
{
dep[x]=dep[fr]+1;
for(auto R:E[x])
if(R!=fr) dfs(R,x),rt[x]=Merge(rt[x],rt[R]),cf[x]+=cf[R];
if(!cf[x]&&x>1) puts("-1"),exit(0);
for(auto P:St[x])
t[++nod].val=A[P].c,t[nod].id=P,rt[x]=Merge(rt[x],nod);
while(dep[A[t[rt[x]].id].y]>=dep[x]) rt[x]=Del(rt[x]);
if(rt[x]) Ans+=t[rt[x]].val,Put(rt[x],-t[rt[x]].val);
}
int main()
{
cin>>n>>m;
for(int i=1,x,y;i<n;i++)
scanf("%d%d",&x,&y),E[x].pb(y),E[y].pb(x);
for(int i=1,x,y,c;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&c);
St[x].pb(i);cf[x]++;cf[y]--;
A[i]=(mmp){x,y,c};
}
dfs(1,0);
cout<<Ans<<endl;
}
[Codeforces671D]Roads in Yusland的更多相关文章
- 题解-Codeforces671D Roads in Yusland
Problem Codeforces-671D 题意概要:给定一棵 \(n\) 点有根树与 \(m\) 条链,链有费用,保证链端点之间为祖先关系,问至少花费多少费用才能覆盖整棵树(\(n-1\) 条边 ...
- codesforces 671D Roads in Yusland
Mayor of Yusland just won the lottery and decided to spent money on something good for town. For exa ...
- 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 ...
- 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序 线段树 算是一个套路.可以处理在树上取链的问题.
- Codeforces 671D. Roads in Yusland(树形DP+线段树)
调了半天居然还能是线段树写错了,药丸 这题大概是类似一个树形DP的东西.设$dp[i]$为修完i这棵子树的最小代价,假设当前点为$x$,但是转移的时候我们不知道子节点到底有没有一条越过$x$的路.如果 ...
随机推荐
- maven构建myeclipse 工程
前提:安装maven完成后 mvn -version查看版本 一,新建WEB 工程 mvn archetype:generate -DgroupId={project-packaging} -Dar ...
- oracle数据库的简单操作
本操作是在oracle的11g版本中的操作 一.数据库登录操作: 如果是在服务器上登录oracle,需要先切换到oracle用户再进行登录 #切换到oracle用户 su - oracle #登录or ...
- Java实现OPC通信
1.PLC和OPC 使用的PLC:西门子的S7 300,具体型号如下图 使用的OPC server软件: 模拟仿真用的 MatrikonOPCSimulation(50M),百度网盘,密码: mcur ...
- OPC和DCOM配置
本文为Java实现OPC通信的一部分 系统:使用win10 64位专业版 PDF文件: 本文,链接: 百度网盘 密码: reht, Win7和Win7_SP1网络OPC配置,链接: 百度网盘 密码 ...
- wav音频文件格式解析【个人笔记】(自用)
1. WAV格式 wav是微软开发的一种音频文件格式,注意,wav文件格式是无损音频文件格式,相对于其他音频格式文件数据是没有经过压缩的,通常文件也相对比较大些.. 支持多种音频数字,取样频率和声道, ...
- vue-if与vue-show的区别
两者都是动态显示DOM元素 不同点: 1.使用方式 v-if是根据后面数据的真假,来判断DOM的添加删除等操作 v-show只是在修改元素的css样式(display属性值) 2.实现过程 v ...
- 905. Sort Array By Parity
Description Given an array A of non-negative integers, return an array consisting of all the even el ...
- EFCodeFirst示例
1.定义一个基础模板类 namespace WebApplication1.Models { /// <summary> /// 可持久到数据库的领域模型的基类. /// </sum ...
- Python字符串方法总结(一)
1.find 在一个较长的字符串中查找子串.它返回子串所在位置的最左端索引.如果没有找到则返回-1 2.split 将字符串用给定的分隔符分割成序列,当没有提供分隔符时,默认把所有空格作为分隔符 3. ...
- html5 缓存实例
html5 有两种缓存 1.localStorage:浏览器关闭后,数据库还存在. 2.sessionStorage:session缓存,浏览器关闭后,数据已经不存在. 实例一:localStorag ...