首先O(n2)dp很好想

f[i][j]表示i子树内的所有边都被覆盖且i~j的路径也都被覆盖的最小花费。

考虑去掉无用的状态,其实真正用到的就是每一条链。

去掉第二维,f[i]表示i子树内的边都被覆盖且父向边也被覆盖的最小花费。

那么怎么转移呢?

f[i]可以是任意一条包含i和fa[i]的链转移而来,

首先要选这条链,还要加上这条链下端点到i所有其他儿子的f值,这样复杂度好像依旧很高

再优化,这不就是线段树取一个min吗?

那么我们现在要做的就是在每一个点上,在对应的一些链中取一个min

对于每条链,它是在它的下端点之上开始做出贡献的,

所以每个点控制的区间要是它的子树中所有向上连的边

当我们搞点x时,首先要算出他所有儿子的f值加和sum.然后要将以x为下端点的链的值更新为sum+c[i],还要将所有以x为上端点的链赋值inf,还要对其所有儿子的控制的链都加上sum-f[son],最后对于他控制的所有链取一个min就好了.

代码

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define N 300005
#define inf 1000000000000000ll
#define LL long long
using namespace std;
int n,m,c[N];
int e=,head[N],out[N],in[N];
struct edge{int v,next;}ed[*N];
void add(int u,int v,int *h){
ed[e]=(edge){v,h[u]};
h[u]=e++;
}
int L[N],R[N],tot,d[N];
void dfs(int x,int fa){
L[x]=tot+;
for(int i=in[x];i;i=ed[i].next)
d[ed[i].v]=++tot;
for(int i=head[x];i;i=ed[i].next)
if(ed[i].v!=fa)dfs(ed[i].v,x);
R[x]=tot;
}
LL f[N];
LL minn[*N],lazy[*N];
void update(int rt,int l,int r,int x,LL y){
if(l==r){minn[rt]=y;return ;}
int mid=(l+r)>>;
if(x<=mid)update(rt<<,l,mid,x,y);
else update(rt<<|,mid+,r,x,y);
minn[rt]=min(min(minn[rt<<],minn[rt<<|])+lazy[rt],inf);
}
void add(int rt,int l,int r,int x,int y,LL z){
if(x<=l&&r<=y){lazy[rt]+=z;minn[rt]+=z;return ;}
int mid=(l+r)>>;
if(x<=mid) add(rt<<,l,mid,x,y,z);
if(y>mid) add(rt<<|,mid+,r,x,y,z);
minn[rt]=min(min(minn[rt<<],minn[rt<<|])+lazy[rt],inf);
}
LL query(int rt,int l,int r,int x,int y){
if(x<=l&&r<=y) return minn[rt];
LL ans=inf;
int mid=(l+r)>>;
if(x<=mid)ans=min(ans,query(rt<<,l,mid,x,y));
if(y>mid) ans=min(ans,query(rt<<|,mid+,r,x,y));
return min(ans+lazy[rt],inf);
}
void solve(int x,int fa){
LL ans=;
for(int i=head[x];i;i=ed[i].next){
if(ed[i].v==fa)continue;
solve(ed[i].v,x);
ans=min(f[ed[i].v]+ans,inf);
}
if(x==){f[]=ans;return;}
for(int i=in[x];i;i=ed[i].next)
update(,,m,d[ed[i].v],ans+c[ed[i].v]);
for(int i=out[x];i;i=ed[i].next)
update(,,m,d[ed[i].v],inf);
for(int i=head[x];i;i=ed[i].next){
if(ed[i].v==fa)continue;
add(,,m,L[ed[i].v],R[ed[i].v],ans-f[ed[i].v]);
}
f[x]=query(,,m,L[x],R[x]);
} int main(){
scanf("%d%d",&n,&m);
for(int i=,u,v;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v,head);
add(v,u,head);
}
for(int i=,u,v;i<=m;i++){
scanf("%d%d%d",&u,&v,&c[i]);
add(u,i,in);
add(v,i,out);
}
dfs(,);
memset(minn,0x15f,sizeof minn);
memset(lazy,,sizeof lazy);
solve(,);
if(f[]>=inf)printf("-1\n");
else printf("%lld\n",f[]);
return ;
}

youmu

codeforces 671D的更多相关文章

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

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

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

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

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

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

  4. python爬虫学习(5) —— 扒一下codeforces题面

    上一次我们拿学校的URP做了个小小的demo.... 其实我们还可以把每个学生的证件照爬下来做成一个证件照校花校草评比 另外也可以写一个物理实验自动选课... 但是出于多种原因,,还是绕开这些敏感话题 ...

  5. 【Codeforces 738D】Sea Battle(贪心)

    http://codeforces.com/contest/738/problem/D Galya is playing one-dimensional Sea Battle on a 1 × n g ...

  6. 【Codeforces 738C】Road to Cinema

    http://codeforces.com/contest/738/problem/C Vasya is currently at a car rental service, and he wants ...

  7. 【Codeforces 738A】Interview with Oleg

    http://codeforces.com/contest/738/problem/A Polycarp has interviewed Oleg and has written the interv ...

  8. CodeForces - 662A Gambling Nim

    http://codeforces.com/problemset/problem/662/A 题目大意: 给定n(n <= 500000)张卡片,每张卡片的两个面都写有数字,每个面都有0.5的概 ...

  9. CodeForces - 274B Zero Tree

    http://codeforces.com/problemset/problem/274/B 题目大意: 给定你一颗树,每个点上有权值. 现在你每次取出这颗树的一颗子树(即点集和边集均是原图的子集的连 ...

随机推荐

  1. 《HelloGitHub》第 25 期

    <HelloGitHub>第 25 期 兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程. ...

  2. Testng基本问题

    Testng testng.xml suite属性说明: suite verbose="4" 命令行信息打印等级 1~5 parallel 是否多线程并发运行测试:可选值(fals ...

  3. Ng1从1.3开始的变更史

    从今有个ng1 spa项目,项目可能会有ng1的版本升级问题,特简要摘录从1.3的主要版本变更,所以内容来自migration guide. 1.3的主要变更: 1.controller不能再以全局简 ...

  4. 大型三甲医院医疗体检信息管理系统源码 PEIS 体检科软件 CS

    详情请点击查看 开发环境 :VS2008 + C# + SQL2000 功能介绍: 1:设置:操作员设置   系统功能设置    用户组权限设置  公告打印设置  数据字典设置  临床类型设置  体检 ...

  5. python笔记:#008#变量的命名

    变量的命名 目标 标识符和关键字 变量的命名规则 0.1 标识符和关键字 1.1 标识符 标示符就是程序员定义的 变量名.函数名 名字 需要有 见名知义 的效果,见下图: 标示符可以由 字母.下划线 ...

  6. eclipse配置tomcat后启动报内存错误解决方法

    一.双击tomcat服务,打开配置界面 二.打开launch configuration窗口,在Argument最后面加入:-Xms256m -Xmx512m -XX:PermSize=256M -X ...

  7. 论文笔记(1):Deep Learning.

    论文笔记1:Deep Learning         2015年,深度学习三位大牛(Yann LeCun,Yoshua Bengio & Geoffrey Hinton),合作在Nature ...

  8. Maven打包详细流程

    方法一:cmd 控制台打包(比较不推荐) 首先安装maven插件百度下载一个,配置环境变量什么的~在cmd控制台能mvn version能有数据出现. 打包只需要到项目的根目录下~在cmd敲入mvn ...

  9. httpd基础配置和虚拟主机的配置方法

    RedHat6.5  httpd实验的大概步骤 #解包 tar zxf httpd-2.2.17.tar.gz -C /usr/src#切换到目录 cd /usr/src/httpd-2.2.17/# ...

  10. 谈谈书本《c#物联网程序设计基础》中的技术瑕疵,如果你将要读本书,请进来看看!

    今天去书店看到一本名为<c#物联网程序设计基础>的书,对物联网感兴趣的我抓起来就看,书中的项目都是上位机开发项目,较简单,如果物联网开发只是这样,看起来我做物联网开发也是绰绰有余.这边书我 ...