[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的更多相关文章

  1. 题解-Codeforces671D Roads in Yusland

    Problem Codeforces-671D 题意概要:给定一棵 \(n\) 点有根树与 \(m\) 条链,链有费用,保证链端点之间为祖先关系,问至少花费多少费用才能覆盖整棵树(\(n-1\) 条边 ...

  2. codesforces 671D Roads in Yusland

    Mayor of Yusland just won the lottery and decided to spent money on something good for town. For exa ...

  3. Codeforces 671 D. Roads in Yusland

    题目描述 Mayor of Yusland just won the lottery and decided to spent money on something good for town. Fo ...

  4. 【CF671D】Roads in Yusland(贪心,左偏树)

    [CF671D]Roads in Yusland(贪心,左偏树) 题面 洛谷 CF 题解 无解的情况随便怎么搞搞提前处理掉. 通过严密(大雾)地推导后,发现问题可以转化成这个问题: 给定一棵树,每条边 ...

  5. 【CF617D】Roads in Yusland

    [CF617D]Roads in Yusland 题面 蒯的洛谷的 题解 我们现在已经转化好了题目了,戳这里 那么我们考虑怎么求这个东西,我们先判断一下是否所有的边都能被覆盖,不行的话输出\(-1\) ...

  6. 【CodeForces】671 D. Roads in Yusland

    [题目]D. Roads in Yusland [题意]给定n个点的树,m条从下往上的链,每条链代价ci,求最少代价使得链覆盖所有边.n,m<=3*10^5,ci<=10^9,time=4 ...

  7. Codeforces 671D Roads in Yusland [树形DP,线段树合并]

    洛谷 Codeforces 这是一个非正解,被正解暴踩,但它还是过了. 思路 首先很容易想到DP. 设\(dp_{x,i}\)表示\(x\)子树全部被覆盖,而且向上恰好延伸到\(dep=i\)的位置, ...

  8. codeforces 671D Roads in Yusland & hdu 5293 Tree chain problem

    dp dp优化 dfs序 线段树 算是一个套路.可以处理在树上取链的问题.

  9. Codeforces 671D. Roads in Yusland(树形DP+线段树)

    调了半天居然还能是线段树写错了,药丸 这题大概是类似一个树形DP的东西.设$dp[i]$为修完i这棵子树的最小代价,假设当前点为$x$,但是转移的时候我们不知道子节点到底有没有一条越过$x$的路.如果 ...

随机推荐

  1. python js(JavaScript)初识

    ####################总结############## 引入: 可以在body标签中放入<script type=”text/javascript”></scrip ...

  2. .net面式题

    .Net httphandler与httpmodule区别 动态控件在postback能否保存下来(不能) 序列化(对象到其他格式(xml/json/byte...)JavaScriptSeriali ...

  3. [转]Red Hat Linux相关产品iso镜像下载【百度云】

    超强汇总!献上大佬链接:http://www.linuxfly.org/post/659/ 还有一些可用链接: 下面的直接复制到迅雷下载,链接是打不开的. RHEL 5.4 ISO下载http://r ...

  4. GIL 全局解释器

    全局解释器锁 GIL 相当于给python解释器加了一把互斥锁 每一个进程都有一把互斥锁,所有线程必须先拿到解释器,才能执行代码, 同一进程下,所有线程并发 在 Cpython 解释器下,多个进程可以 ...

  5. Silverlight 样式的灵活使用

    众所周知,Silverlight将界面设计与代码实现分开.即便如此,如果不能灵活地运用样式Style,开发的效率依然会比较低.比如,针对类似的TextBlock,你可能需要反复地在设计器xaml中复制 ...

  6. vue 获取时间戳对象转换为日期格式

    //1. 简单页面展示用<template> <!-- time为时间戳 --> <div>{{time | formatDate}}</div> &l ...

  7. Left join update和 ROW_NUMBER

    (1)Left join 更新update a set a.name=b.name from a left join b on a.id=b.stuid(2)ROW_NUMBERselect ROW_ ...

  8. Polymer初探

    Polymer是什么? Polymer英文为 n.聚合物:多聚体 网络高分子:聚合体:高分子聚合物 应用在Web组件场景, 表达的是, 一个一个小的Web组件,可以通过此框架聚合为一个 整个页面. h ...

  9. 三、文件IO——系统调用(续)

    3.2.4 read 函数--- 读文件 read(由已打开的文件读取数据) #include<unistd.h> ssize_t read(int fd, void * buf, siz ...

  10. mariadb开启远程访问

    安装好mariadb之后,开启防火墙端口,但是还是远程访问,一顿百度之后,找到原因 使MariaDB允许远程访问 确定服务器上的防火墙没有阻止 3306 端口 使用nestat命令查看3306端口状态 ...