[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. Jquery Pagination分页插件使用

    JqueryPagination是个简单轻量级的分页插件,使用起来很容易,只要初始化一个实例,并设置总数量.翻页回调函数.其它参数就可以实现无刷新分页功能了. 准备工作 下载jquery.min.js ...

  2. Tomcat、Weblogic、WebSphere、JBoss服务器的选择

    一.应用点 Tomcat是Apache基金会提供的Servlet容器,它支持JSP, Servlet和JDBC等J2EE关键技术,所以用户可以用Tomcat开发基于数据库,Servlet和JSP页面的 ...

  3. javasrcipt的作用域和闭包(二)

    这篇博客主要对词法作用域与欺骗词法作用域.函数作用域与块级作用域.函数内部的变量提成原理进行详细的分析,在这篇博客之前,关于作用域.编译原理.浏览器引擎的原理及关系在javaScript的作用域和闭包 ...

  4. IO流--序列化流与反序列化流

    IO流--序列化流与反序列化流: 序列化流:把对象当做流一样写入到文本文件中 ObjectOutputSream(); 反序列化流:把文本文件中的流对象还原成对象ObjectInputSream(): ...

  5. pycharm仿sublime配色

    1.设置IDE皮肤主题 file->setting->appearance->theme->darcula 2.setting中搜索python,将主题设置成Monokai,然 ...

  6. 22.doublewrite/ChangeBuffer/AHI/FNP

    一. Double Write1 Double Write介绍 • Double Write的目的是为了保证数据写入的可靠性, 避免partial write 的情况 ◦ partial write( ...

  7. Docker 创建 mongo 容器

    获取 docker 认证 mongo 镜像: docker pull mongo 创建运行 mongo 容器: docker run -d -it -p : --name mongo3 -m 512M ...

  8. 初识生成器与生成器表达式 Day12

    一.生成器 1,生成器基本概念 生成器的实质是迭代器 迭代器:Iterator 内部同时包含了__iter__()和__next__()函数 可迭代对象:Iterable 内部包含__iter__() ...

  9. 第25月25日 urlsession

    1. private lazy var session: URLSession = { let configuration = URLSessionConfiguration.default conf ...

  10. Shiro入门 - 通过ini文件进行认证

    导入依赖 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-core ...