[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 ...
随机推荐
- UE4技术总结——委托
UE4技术总结--委托 目录 UE4技术总结--委托 一.定义 二.用法 2.1 声明与调用委托 2.1.1 单播委托 2.1.1.a 声明 2.1.1.b 绑定 2.1.1.c 执行委托 2.1.1 ...
- SQL SERVER数据库权限分配
1,新建 只能访问某一个表的只读用户. --添加只允许访问指定表的用户: exec sp_addlogin '用户名','密码','默认数据库名' ...
- QQ三国 秘制机簧去哪打?打的太慢?
我在完成这个任务时卡了很久,因为打的效率极低,因此最后我是如何完成的. 1. 先说打谁吧,刚开始我打机簧蜘蛛,就没打出来过,,后来换了机簧车,掉率就上升了,建议打机簧车. 2. 如果你一直打不出来,建 ...
- transformers---BERT
transformers---BERT BERT模型主要包括两个部分,encoder和decoder,encoder可以理解为一个加强版的word2vec模型,以下是对于encoder部分的内容 预训 ...
- Tomcat实现自定义类加载器
什么是类加载器? 这是官方给的定义 在 Java 虚拟机的实现中,初始类可以作为命令行参数提供. 或者,该实现可以提供一个初始类,该类设置一个类加载器,该类加载器依次加载应用程序. 初始类的其他选择也 ...
- PAT (Basic Level) Practice (中文)1031 查验身份证 (15分)
1031 查验身份证 (15分) 一个合法的身份证号码由17位地区.日期编号和顺序编号加1位校验码组成.校验码的计算规则如下: 首先对前17位数字加权求和,权重分配为: {7,9,10,5,8,4,2 ...
- 【UE4 设计模式】享元模式 Flyweight Pattern
概述 描述 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用. 由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻 ...
- vue3.x移动端适配px2rem
1.什么是px2rem px2rem是一个插件能将px自动转换为rem,以适配各种不同的屏幕尺寸.前端开发可以直接使用设计稿量出的尺寸或者蓝湖给出的px进行布局,这样极大的提高了开发效率. 2.前提条 ...
- python标准库glob 递归目录下所有文件
import glob for i in glob.glob(r'C:\Desktop\**',recursive=True): print(i) """ re:?*[0 ...
- Ubuntu 用户管理/权限管理
Ubuntu 用户管理/权限管理 小小记录一下 Ubuntu 下用户/权限管理常用的一些命令 用户管理 组管理 文件权限 给用户添加 sudo 权限 给用户添加 sudo 权限 首先先给出几个文件 / ...