[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 ...
随机推荐
- 前端快闪四: 拦截axios请求和响应
马甲哥继续在同程艺龙写一点大前端: 今天我们来了解一下 如何拦截axios请求/响应? axios是一个基于 promise 的网络请求库,可以用于浏览器和 node.js, promise 类似于C ...
- Linux下关于用户账户的几个文件解析
Linux下关于用户账户的几个文件解析 Linux是一个多用户系统,但是对于一个多用户共存的系统中,当然不能够出现用户相互越权等一系列的安全问题,所以如何正确的管理账户成为了Linux系统中至关重要的 ...
- 洛谷3288 SCOI2014方伯伯运椰子(分数规划+spfa)
纪念博客又一次爆炸了 首先,对于本题中,我们可以发现,保证存在正整数解,就表示一定费用会降低.又因为一旦加大的流量,费用一定会变大,所以总流量一定是不变的 那么我们这时候就需要考虑一个退流的过程 对于 ...
- HTML5背景知识
目录 HTML5背景知识 HTML的历史 JavaScript出场 浏览器战争的结束 插件称雄 语义HTML浮出水面 发展态势:HTML标准滞后于其使用 HTML5简介 新标准 引入原生多媒体支持 引 ...
- 【NXOpen.UF扩展】修改表达式
public static class UFExpEx { /// <summary> /// 修改当前部件的表达式 /// </summary> /// <param ...
- C++控制台应用程序一闪而过的解决方法
Visual Studio 2017 C++控制台应用程序, 如果编译时发现黑框一闪而过,请按以下步骤操作: 右键project → 属性 → 链接器 → 系统 → 子系统,在下拉菜单中改为控制台.
- css如何简单设置文字溢出盒子显示省略号
1.单行文本溢出显示省略号单行文本溢出显示省略号,必须满足三个条件:(1)先强制一行内显示文本white-space:nowrap;(默认 normal自动换行)(2)超出的部分隐藏overflow: ...
- [BZOJ3307] 雨天的尾巴-----------------线段树进阶
虽然是个板子,但用到了差分思想. Description N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最 ...
- webshell绕过D盾
PHP常见的代码执行函数: eval() assert() preg_replace() create_function() array_map() call_user_func() call_use ...
- 跳台阶 牛客网 剑指Offer
跳台阶 牛客网 剑指Offer 题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). class Solution: #ru ...