[hdu6974]Destinations
注意到一个人的三条链一定不会同时选(忽略仅选一个终点的限制),因为其有公共点(起点)
换言之,问题相当于给定$3m$条链,选择$m$条没有公共点的链,并最小化代价和
进一步的,显然也不存在多于$m$条且没有公共点的链,因此"选择$m$条链"也可以理解为选尽量多的链(若选不到$m$条链即为-1)的同时最小化代价和
更进一步的,只需要将每一条链的代价从$c$变为$C-c$(其中$C$为足够大量,可以设为$10^{12}$),即可忽略"选尽量多的链"的条件(注意代价取了相反数)
综上,问题即相当于给定$3m$条链,选择若干条没有公共点的链,并最大化代价和
设最终答案为$ans$,若$ans\le (m-1)C$答案为-1,否则答案为$mC-ans$
对于这个问题,考虑其对偶问题:给每一个点一个非负整数的权值,要求每一条链上所有点的权值和不小于该链的代价,求最小的权值和
两者的答案是相同的,证明如下——
假设最小的权值和为$sum$,由于一条链的权值小于等于该链上所有点权值和,那么对于一种选链的方案,权值总和即小于等于所有经过的点权值和,注意到没有重复点且权值非负,即得到$ans\le sum$
另一方面,考虑贪心的构造这个最小的权值和,即从底向上依次选择权值,使得以其为lca的路径都满足条件且最小(若不存在路径或都已经满足则设为0)
此时,不断找到最浅的且未被经过的节点,若该点边权为0则跳过,否则必然恰有一条以其为lca且权值和恰等于路径上边权和的链,选择其并重复此过程,最终不难得到$ans\ge sum$
综上,有$ans=sum$,即得证
从证明过程中,也得到了该问题的贪心做法,其的维护即要支持单点修改+链查询,再通过差分转换为子树修改+单点查询,并使用树状数组维护即可
时间复杂度为$o(n\log n)$,可以通过


1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define ll long long
5 struct Edge{
6 int nex,to;
7 }edge[N<<1];
8 struct Data{
9 int x,y;
10 ll z;
11 };
12 vector<Data>v[N];
13 int E,t,n,m,x,y,head[N],dfn[N],sz[N],dep[N],fa[N][21];
14 ll C=1e12,z,ans,f[N];
15 void add(int x,int y){
16 edge[E].nex=head[x];
17 edge[E].to=y;
18 head[x]=E++;
19 }
20 int lca(int x,int y){
21 if (dep[x]<dep[y])swap(x,y);
22 for(int i=20;i>=0;i--)
23 if (dep[fa[x][i]]>=dep[y])x=fa[x][i];
24 if (x==y)return x;
25 for(int i=20;i>=0;i--)
26 if (fa[x][i]!=fa[y][i]){
27 x=fa[x][i];
28 y=fa[y][i];
29 }
30 return fa[x][0];
31 }
32 void dfs(int k,int f,int s){
33 dfn[k]=++dfn[0];
34 sz[k]=1;
35 dep[k]=s;
36 fa[k][0]=f;
37 for(int i=1;i<=20;i++)fa[k][i]=fa[fa[k][i-1]][i-1];
38 for(int i=head[k];i!=-1;i=edge[i].nex)
39 if (edge[i].to!=f){
40 dfs(edge[i].to,k,s+1);
41 sz[k]+=sz[edge[i].to];
42 }
43 }
44 int lowbit(int k){
45 return (k&(-k));
46 }
47 void update(int k,ll x){
48 while (k<=n){
49 f[k]+=x;
50 k+=lowbit(k);
51 }
52 }
53 ll query(int k){
54 ll ans=0;
55 while (k){
56 ans+=f[k];
57 k-=lowbit(k);
58 }
59 return ans;
60 }
61 void calc(int k,int fa){
62 for(int i=head[k];i!=-1;i=edge[i].nex)
63 if (edge[i].to!=fa)calc(edge[i].to,k);
64 ll s=0;
65 for(int i=0;i<v[k].size();i++){
66 x=v[k][i].x,y=v[k][i].y,z=v[k][i].z;
67 s=max(s,z-(query(dfn[x])+query(dfn[y])-2*query(dfn[k])));
68 }
69 update(dfn[k],s);
70 update(dfn[k]+sz[k],-s);
71 ans+=s;
72 }
73 int main(){
74 scanf("%d",&t);
75 while (t--){
76 scanf("%d%d",&n,&m);
77 E=ans=dfn[0]=0;
78 for(int i=1;i<=n;i++){
79 head[i]=-1,f[i]=0;
80 v[i].clear();
81 }
82 for(int i=1;i<n;i++){
83 scanf("%d%d",&x,&y);
84 add(x,y);
85 add(y,x);
86 }
87 dfs(1,1,0);
88 for(int i=1;i<=m;i++){
89 scanf("%d",&x);
90 for(int j=1;j<=3;j++){
91 scanf("%d%lld",&y,&z);
92 v[lca(x,y)].push_back(Data{x,y,C-z});
93 }
94 }
95 calc(1,0);
96 if (ans<=C*(m-1))printf("-1\n");
97 else printf("%lld\n",C*m-ans);
98 }
99 return 0;
100 }
[hdu6974]Destinations的更多相关文章
- ActiveMQ(5.10.0) - Wildcards and composite destinations
In this section we’ll look at two useful features of ActiveMQ: subscribing to multiple destinations ...
- streamsets mongodb destinations 使用
测试集成了directory(excel) 以及redis && field splitter 组件 pipeline flow docker-compose 配置 redis 服务& ...
- streamsets redis destinations 使用
测试集成了directory(excel) 以及redis && field splitter 组件 pipeline flow docker-compose 配置 redis 服务& ...
- Archiving not possible: No primary destinations errors
If space ran out in an archive destination, after you fix the problem, you may still recieve the fol ...
- ActiveMQ队列特性:删除不活动的队列(Delete Inactive Destinations)
方法一 通过 ActiveMQ Web 控制台删除. 方法二 通过 Java 代码删除. ActiveMQConnection.destroyDestination(ActiveMQDestinati ...
- ORA-16014: log 3 sequence# 540 not archived, no available destinations
https://blog.csdn.net/zonelan/article/details/7329369
- 【AutoMapper官方文档】DTO与Domin Model相互转换(上)
写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...
- 【AutoMapper官方文档】DTO与Domin Model相互转换(下)
写在前面 AutoMapper目录: [AutoMapper官方文档]DTO与Domin Model相互转换(上) [AutoMapper官方文档]DTO与Domin Model相互转换(中) [Au ...
- Fedora 24中的日志管理
Introduction Log files are files that contain messages about the system, including the kernel, servi ...
随机推荐
- JavaFx 监听剪切板实现(Kotlin)
原文地址: JavaFx 监听剪切板实现(Kotlin) | Stars-One的杂货小窝 软件有个需求,想要实现监听剪切板的内容,若内容符合预期,则进行相关的操作,就可以免去用户手动粘贴的操作,提供 ...
- 纯净Ubuntu16安装CUDA(9.1)和cuDNN
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- IPtable防火墙概念介绍
1.iptables安全优化 1.不配外网,做代理转发或者防火墙映射 2.并发过大,不建议开启防火墙 2.防火墙的工作流程: 按照配置规则的顺序自上而下,从前到后进行过滤 如果匹配上新规则,表明是阻止 ...
- dubbo-admin的使用
目录 了解 dubbo-admin 下载 dubbo-admin 使用 dubbo-admin 1.dubbo-admin是什么 dubbo-admin是一个监控程序,可以通过web很方便的管理监控众 ...
- PAT (Basic Level) Practice (中文)1031 查验身份证 (15分)
1031 查验身份证 (15分) 一个合法的身份证号码由17位地区.日期编号和顺序编号加1位校验码组成.校验码的计算规则如下: 首先对前17位数字加权求和,权重分配为: {7,9,10,5,8,4,2 ...
- Python中的sys.stdin和input、sys.stdout与print--附带讲解剑指offer42-连续子数组的最大和
2020秋招季,终于开始刷第一套真题了,整套试卷就一道编程题,还是剑指offer上的原题,结果答案死活不对,最后干脆直接提交答案算了,看了下别人的答案,原来是输入数据没有获取的原因,不过这个语法sys ...
- Win10 配置JDK1.8 (JDK 8)环境变量
JDK的安装: 1. JDK安装过程中,一般X掉公共JRE,因为JDK包含了JRE: 环境变量的配置: 1. 打开环境变量,编辑系统变量,新建: 变量名:JAVA_HOME 变量值:D:\so ...
- oo第二次博客-三次电梯调度的总结与反思
本单元从电梯调度相关问题层层深入,带领我们学习并运用了了多线程相关的知识. 三次电梯调度依次为单电梯单容量.单电梯可携带.多电梯可携带. 一.我的设计 在第一次作业中,使用了最简单的FIFO调度方法. ...
- netty传输java bean对象
在上一篇博客(netty入门实现简单的echo程序)中,我们知道了如何使用netty发送一个简单的消息,但是这远远是不够的.在这篇博客中,我们来使用netty发送一个java bean对象的消息,但是 ...
- Redis的浅入门
Redis的浅入门 # 缓存的思想 问题提出:我们的用户数量上亿,如果登录,访问数据库user特别耗时,该怎么办?--提出缓存 方法:怎样从缓存在获取数据? *有数据: 直接返回 *无数据: (1)从 ...