题目描述

Mayor of Yusland just won the lottery and decided to spent money on something good for town. For example, repair all the roads in the town.

Yusland consists of n intersections connected by n - 1 bidirectional roads. One can travel from any intersection to any other intersection using only these roads.

There is only one road repairing company in town, named "RC company". Company's center is located at the intersection 1. RC company doesn't repair roads you tell them. Instead, they have workers at some intersections, who can repair only some specific paths. The i-th worker can be paid ci coins and then he repairs all roads on a path from ui to some vi that lies on the path from ui to intersection 1.

Mayor asks you to choose the cheapest way to hire some subset of workers in order to repair all the roads in Yusland. It's allowed that some roads will be repaired more than once.

If it's impossible to repair all roads print  - 1.

题目大意:

每一条边都需要被修建一次,雇佣第\(i\)个工人需要花 \(ci\) 的钱,能够帮你修建 \(ui\),\(vi\),之间的所有道路,并且保证 \(vi\) 是,\(ui\) 到根的路径上的点

解题报告:

用时:2h,6MLE

分析这题,叶子节点必须选,然后对于没有被覆盖的也必须从子树中选,但是需要决策,所以只能DP,考虑状态:

很容易想到最暴力的DP,定义 \(f[x][j]\),表示 \(x\) 子树内的边都被修过,且已选工人最远能覆盖到的深度为 \(j\),转移非常简单,但是复杂度不对,考虑消除第二维:不会.....

容易想到树链剖分,即把当前节点能更新到的父节点做一遍链剖,更新线段树

显然不行,因为不能保证其他子树都被覆盖

参考题解:

思想非常巧妙,大概是把其他子树中的DP值累加到某一棵子树上,这样就巧妙的使得线段树中的DP值都是合法的了,为了消除在 \(vi\) 结束的影响,我们在 \(ui\) 和 \(vi\) 上分别挂链,然后dfs时对应线段树中添加删除即可

注意实现时可以考虑不参考我的方法,其实不一定只对关键点建立线段树,不然细节很多

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const int N=300005;const ll inf=2e15;
int head[N],nxt[N<<2],to[N<<2],num=0,n,m,val[N],dfn[N],DFN=0,L[N],R[N],s[N],t[N];
void link(int x,int y,int *h){nxt[++num]=h[x];to[num]=y;h[x]=num;}
void priwork(int x,int last){
L[x]=DFN+1;
for(int i=s[x];i;i=nxt[i])dfn[to[i]]=++DFN;
for(int i=head[x];i;i=nxt[i])
if(to[i]!=last)priwork(to[i],x);
R[x]=DFN;
}
ll tree[N<<2],mark[N<<2],f[N];
#define ls (node<<1)
#define rs (node<<1|1)
void build(int l,int r,int node){
tree[node]=inf;if(l==r)return ;
int mid=(l+r)>>1;
build(l,mid,ls);build(mid+1,r,rs);
tree[node]=Min(tree[ls],tree[rs]);
}
il void updata(int l,int r,int node,int sa,int se,ll to){
if(sa>se)return ;
if(l>se || r<sa)return ;
if(sa<=l && r<=se){
tree[node]=Min(tree[node]+to,inf);
mark[node]=Min(mark[node]+to,inf);
return ;
}
int mid=(l+r)>>1;
updata(l,mid,ls,sa,se,to);updata(mid+1,r,rs,sa,se,to);
tree[node]=Min(tree[ls],tree[rs])+mark[node];
}
il void Modify(int l,int r,int node,int sa,ll to){
if(l==r){tree[node]=Min(to,inf);return ;}
int mid=(l+r)>>1;
if(sa<=mid)Modify(l,mid,ls,sa,to);
else Modify(mid+1,r,rs,sa,to);
tree[node]=Min(tree[ls],tree[rs])+mark[node];
}
il ll query(int l,int r,int node,int sa,int se){
if(sa>se)return inf;
if(l==sa && r==se)return tree[node];
int mid=(l+r)>>1;
if(sa>mid)return query(mid+1,r,rs,sa,se)+mark[node];
else if(se<=mid)return query(l,mid,ls,sa,se)+mark[node];
return min(query(l,mid,ls,sa,mid),query(mid+1,r,rs,mid+1,se))
+mark[node];
}
il void dfs(int x,int last){
int u;ll tot=0;
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(to[i]==last)continue;
dfs(u,x);
tot+=f[u];tot=Min(tot,inf);
}
if(x==1){f[x]=tot;return ;}
for(int i=s[x];i;i=nxt[i])Modify(1,m,1,dfn[to[i]],tot+val[to[i]]);
for(int i=t[x];i;i=nxt[i])Modify(1,m,1,dfn[to[i]],inf);
for(int i=head[x];i;i=nxt[i]){
u=to[i];if(u==last)continue;
updata(1,m,1,L[u],R[u],tot-f[u]);
}
f[x]=query(1,m,1,L[x],R[x]);
}
void work()
{
int x,y;
scanf("%d%d",&n,&m);
for(int i=1;i<n;i++){
scanf("%d%d",&x,&y);
link(x,y,head);link(y,x,head);
}
for(int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&val[i]);
link(x,i,s);link(y,i,t);
}
priwork(1,1);build(1,m,1);dfs(1,1);
if(f[1]!=inf)printf("%lld\n",f[1]);
else puts("-1");
} int main(){work();return 0;}

Codeforces 671 D. 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 ...

  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. 【CF671D】Roads in Yusland(贪心,左偏树)

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

  4. [Codeforces671D]Roads in Yusland

    [Codeforces671D]Roads in Yusland Tags:题解 题意 luogu 给定以1为根的一棵树,有\(m\)条直上直下的有代价的链,求选一些链把所有边覆盖的最小代价.若无解输 ...

  5. 【CF617D】Roads in Yusland

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

  6. Codeforces 835 F. Roads in the Kingdom

    \(>Codeforces\space835 F. Roads in the Kingdom<\) 题目大意 : 给你一棵 \(n\) 个点构成的树基环树,你需要删掉一条环边,使其变成一颗 ...

  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. Flask 视图

    写个验证用户登录的装饰器:在调用函数前,先检查session里有没有用户 from functools import wraps from flask import session, abort de ...

  2. Struts2之配置文件中Action的详细配置

    在Struts2之配置一文中,我们知道一个struts配置文件可以分为三部分:常量配置    包含其他配置文件的配置    Action配置  . 这其中 常量配置  和 包含其他配置文件的配置  二 ...

  3. Node.js系列文章:编写自己的命令行界面程序(CLI)

    CLI的全称是Command-line Interface(命令行界面),即在命令行接受用户的键盘输入并作出响应和执行的程序. 在Node.js中,全局安装的包一般都具有命令行界面的功能,例如我们用于 ...

  4. Python爬虫之urllib模块1

    Python爬虫之urllib模块1 本文来自网友投稿.作者PG,一个待毕业待就业二流大学生.玄魂工作室未对该文章内容做任何改变. 因为本人一直对推理悬疑比较感兴趣,所以这次爬取的网站也是平时看一些悬 ...

  5. vscode使用shell

    https://stackoverflow.com/questions/42606837/how-to-use-bash-on-windows-from-visual-studio-code-inte ...

  6. cookieUtil

    public class CookieUtil { /** * 设置cookie * @param name cookie名字 * @param value cookie值 * @param maxA ...

  7. 图数据库orientDB(1-1)SQL基本操作

    SQL基本操作 1.新增VerTex CREATE VERTEX V SET name="user01",sex="M",age="25"; ...

  8. ELK学习总结(3-3)elk的组合查询

    1.bool 查询: must: 必须 should:  可以满足,也可以不满足. must_not: minimum_should_match: 至少要x个匹配才算匹配成功 disable_coor ...

  9. java配置环境变量,无法也行javac问题

    最近换了公司,搭建开发环境的时候出了点小差错,写篇随笔记录下,下载jdk的时候要选择符合自己电脑的jdk版本,位数. 笔者之前下载的时候没注意下了个32bit的jdk,开发用eclipse的时候打不开 ...

  10. python--socket套接字/TCP

    socket套接字/TCP 一 客户端/服务器架构 C/S架构,包括 硬件C/S架构(打印机) 软件C/S 架构(web服务) C/S架构的软件(软件属于应用层)是基于网络进行通信的 Server端要 ...