问题即:选择价值和最多的链,使得每个点最多被一条链覆盖。

那么考虑其对偶问题:选择最少的点(每个点可以重复选),使得每条链上选了至少$w_i$个点。

那么将链按照LCA的深度从大到小排序,每次若发现点数不够,则在LCA处补充点,树链剖分+线段树维护。

时间复杂度$O(m\log^2n)$。

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100010,M=262150;
int Case,cas,n,m,q,i,op,x,y,z;
int g[N],v[N<<1],nxt[N<<1],ed;
int size[N],son[N],f[N],d[N],st[N],top[N],dfn;
int val[M];
int ans;
struct E{int x,y,z,w;}e[N];
inline bool cmp(const E&a,const E&b){return d[a.z]<d[b.z];}
inline void addedge(int x,int y){v[++ed]=y;nxt[ed]=g[x];g[x]=ed;}
void dfs(int x){
size[x]=1;
for(int i=g[x];i;i=nxt[i])if(v[i]!=f[x]){
f[v[i]]=x,d[v[i]]=d[x]+1;
dfs(v[i]),size[x]+=size[v[i]];
if(size[v[i]]>size[son[x]])son[x]=v[i];
}
}
void dfs2(int x,int y){
st[x]=++dfn;top[x]=y;
if(son[x])dfs2(son[x],y);
for(int i=g[x];i;i=nxt[i])if(v[i]!=son[x]&&v[i]!=f[x])dfs2(v[i],v[i]);
}
void build(int x,int a,int b){
val[x]=0;
if(a==b)return;
int mid=(a+b)>>1;
build(x<<1,a,mid),build(x<<1|1,mid+1,b);
}
void change(int x,int a,int b,int c,int p){
val[x]+=p;
if(a==b)return;
int mid=(a+b)>>1;
if(c<=mid)change(x<<1,a,mid,c,p);
else change(x<<1|1,mid+1,b,c,p);
}
int ask(int x,int a,int b,int c,int d){
if(c<=a&&b<=d)return val[x];
int mid=(a+b)>>1,t=0;
if(c<=mid)t=ask(x<<1,a,mid,c,d);
if(d>mid)t+=ask(x<<1|1,mid+1,b,c,d);
return t;
}
inline int lca(int x,int y){
for(;top[x]!=top[y];x=f[top[x]])if(d[top[x]]<d[top[y]])swap(x,y);
return d[x]<d[y]?x:y;
}
inline int chain(int x,int y){
int t=0;
for(;top[x]!=top[y];x=f[top[x]]){
if(d[top[x]]<d[top[y]])swap(x,y);
t+=ask(1,1,n,st[top[x]],st[x]);
}
if(d[x]<d[y])swap(x,y);
t+=ask(1,1,n,st[y],st[x]);
return t;
}
inline void gao(int x,int y,int z,int w){
int t=chain(x,y);
if(t>=w)return;
w-=t;
ans+=w;
change(1,1,n,st[z],w);
}
int main(){
scanf("%d",&Case);
while(Case--){
scanf("%d%d",&n,&m);
for(i=1;i<n;i++){
scanf("%d%d",&x,&y);
addedge(x,y),addedge(y,x);
}
dfs(1);
dfs2(1,1);
build(1,1,n);
for(i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&e[i].w);
e[i].x=x,e[i].y=y;
e[i].z=lca(x,y);
}
sort(e+1,e+m+1,cmp);
for(i=m;i;i--)gao(e[i].x,e[i].y,e[i].z,e[i].w);
printf("%d\n",ans);
for(i=0;i<=n;i++)g[i]=size[i]=son[i]=f[i]=d[i]=st[i]=top[i]=0;
ed=dfn=ans=0;
}
}

  

HDU5293 : Tree chain problem的更多相关文章

  1. hdu5293 Tree chain problem 树形dp+线段树

    题目:pid=5293">http://acm.hdu.edu.cn/showproblem.php?pid=5293 在一棵树中,给出若干条链和链的权值.求选取不相交的链使得权值和最 ...

  2. hdu5293(2015多校1)--Tree chain problem(树状dp)

    Tree chain problem Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Other ...

  3. 【HDU 5233】Tree chain problem (树形DP+树剖+线段树|树状数组)最大权不相交树链集

    [题目] Tree chain problem Problem Description Coco has a tree, whose vertices are conveniently labeled ...

  4. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

  5. 刷题总结——Tree chain problem(HDU 5293 树形dp+dfs序+树状数组)

    题目: Problem Description Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There ar ...

  6. (中等) HDU 5293 Tree chain problem,树链剖分+树形DP。

    Problem Description   Coco has a tree, whose vertices are conveniently labeled by 1,2,…,n.There are ...

  7. 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)

    题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...

  8. HDU 5293 Tree chain problem 树形dp+dfs序+树状数组+LCA

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5293 题意: 给你一些链,每条链都有自己的价值,求不相交不重合的链能够组成的最大价值. 题解: 树形 ...

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

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

随机推荐

  1. ubuntu下配置反向代理

    1. 环境 ubuntu:Ubuntu 13.04 x86-64 apache2: 2.2.22-6ubuntu5.1 amd64 2. 配置 2.1  配置应用 增加监听端口 打开/etc/apac ...

  2. RHEL7恢复root密码

    RHEL7恢复root密码 首先关闭SELINUX [root@panda ~]# getenforce Disabled 然后重启,按↑↓键,进入如下界面,选择第一项,按下e键进行编辑 在此界面找到 ...

  3. python网络爬虫day1

    python爬虫真的很方便,自己不能忽视的问题就是字符编码的问题,一直想腾出时间来看,一直没有时间.明天开始看吧. 今天是学习python爬虫的第一天,从B站上搜到的,可惜可惜. import req ...

  4. SQL Server等待

    等待大概分为3类:资源等待.队列等待.外部等待 过滤掉系统相关的等待类型的语句.(查看常用的等待信息) SELECT wait_type , signal_wait_time_ms , wait_ti ...

  5. Asp.Net MVC Ajax轮训解决Session失效时间

    这种方法不是太好,对服务器得压力大,由于系统是内部人员使用,业务有比较复杂,所以有些值得需要Session去保存,但是,Session有失效时间. 代码如下: $(function () { func ...

  6. Java 骚操作--生成二维码

    https://www.cnblogs.com/lsy131479/p/8808172.html

  7. nodejs 2017

    1.  nodejs函数 path()  nodejs全局变量 __dirname a.js // 运行 node a.js var path = require('path'); console.l ...

  8. 分享微信h5支付源码

    类库代码 wechatH5Pay.php <?php //use Flight; /** * 微信支付服务器端下单 * 微信APP支付文档地址: https://pay.weixin.qq.co ...

  9. js 给定时间,如'2013-08-30',换算和今天的天数差

    由于项目中需要用到给定时间格式,如'2013-08-30',需要计算其和当前时间的间隔,需要算出间隔的时间,自己在网上搜索,并做了下简单的整理,总体思路分3步:1.将给定的时间和当前时间转换为毫秒 2 ...

  10. CentOS6—HAProxy安装与配置

    概述 Haproxy下载地址:http://pkgs.fedoraproject.org/repo/pkgs/haproxy/ 关闭SElinux.配置防火墙 1.vi /etc/selinux/co ...