当前位置: 首页 > news >正文

题解:luogu P4775([NOI2018] 情报中心)

1. Description

给定一棵树 \(T=(V,E)\),边带有整数权值 \(c(e)\)
\(m\) 条路径,第 \(i\) 条路径以节点对 \((x_i,y_i)\) 给出,对应边集 $ P_i \subseteq E $ 为其唯一简单路径上的所有边,且该路径有整数代价 \(v_i\)

要求选取两不同的路径 \(i,j,i\neq j\),满足 \(P_i\cap P_j\neq\varnothing\)
收益定义为并集边权和 \(\sum_{e\in P_i\cup P_j}c(e)\),代价为 \(v_i+v_j\)
求最大化的净收益值 $\max_{i\neq j,P_i\cap P_j\neq \varnothing}\left(\sum_{e\in P_i \cup P_j}c(e)-(v_i+v_j)\right) $。
若不存在满足条件的路径对,则输出“F”。允许结果为负。

2. Solution

本题解思路参考这篇题解。

首先一个关键结论,两条有交的链 \((x_1,y_1),(x_2,y_2)\) 的并集的边权和是 \(\frac{\operatorname{dist}(x_1,y_1)+\operatorname{dist}(x_2,y_2)+\operatorname{dist}(x_1,x_2)+\operatorname{dist}(y_1,y_2)}{2}\),所以我们就可以尝试求出 \(\max (\operatorname{dist}(x_j,y_j)+\operatorname{dist}(x_i,y_i)+\operatorname{dist}(x_i,x_j)+\operatorname{dist}(y_i,y_j)-2v_i-2v_j)\),也即所求答案的两倍。
考虑枚举 \(\operatorname{LCA}(x_i,x_j)=t\),则我们就要求:

  1. \(x_i,x_j\) 处于 \(t\) 的两棵不同子树上。
  2. 最大化 \(\operatorname{dist}(x_j,y_j)+\operatorname{dist}(x_i,y_i)+\operatorname{dist}(x_i,x_j)+\operatorname{dist}(y_i,y_j)-2v_i-2v_j\)

由于 \(\operatorname{dist(x_i,x_j)}=dis_{x_i}+dis_{x_j}-2dis_{t}\),所以我们就只需要最大化 \(dis_{x_i}+dis_{x_j}+\operatorname{dist}(x_i,y_i)+\operatorname{dist}(x_i,x_j)+\operatorname{dist}(y_i,y_j)-2v_i-2v_j\),我们不妨考虑将 \(\operatorname{dist}(x_i,y_i)-2v_i\) 作为点权挂在 \(y_i\) 上,则上述过程相当于维护一个点集,并且求出带权点对最远距离。
由于这个问题是在树上的,所以这个东西其实相当于虚树上的带权直径。
根据树的直径的经典结论,我们合并两个点集的时候,假设原来的两个点集中的最远点对分别是 \((p_1,q_1),(p_2,q_2)\),则合并之后的点集中的最远点对 \((p^\prime,q^\prime)\),满足 \((p^\prime,q^\prime)\in \{(p_1,q_1),(p_1,p_2),(p_1,q_2),(q_1,p_2),(q_1,q_2),(p_2,q_2)\}\),这显然对于带点权的情况也是成立的,具体的,可以通过在 \(u\) 下增加一个叶子,边权为 \(val_u\),即可转换成正常的直径问题。
则我们通过上面做法,可以快速合并点集,并求出合并之后的答案。
我们想到可以利用线段树合并来维护点集,现在的问题是,我们需要在一些恰当的时候删除点集中的一些点。
对于一条路径 \((x,y)\),假设 \(lca=\operatorname{LCA}(x,y)\),他可以与其他路径匹配,当且仅当我们枚举的点 \(t\) 不为 \(lca\),且是 \(x\)\(y\) 的祖先,则利用类似树上差分的方法可以维护点集。

3. Code

/*by ChenMuJiu*/
/*略去缺省源与快读快写*/
const int N=5e4+5,M=1e5+5;
const ll inf=8e18;
int n,m,cnt_dfn;
ll ans;
int st[20][N<<1],fa[20][N<<1],dep[N],dfn[N],rt[N];
ll dis[N],val[N];
vector<pii>e[N];
vector<int>erase[N],insert[N];
struct Line{int x,y;ll v;
}b[M];
int LCA(int u,int v){if(u==v)return u;if(dfn[u]>dfn[v])swap(u,v);u=dfn[u],v=dfn[v];int j=__lg(v-u+1);return Min(st[j][u],st[j][v-(1<<j)+1]);
}
int jump(int u,int depth){if(depth>dep[u])return -1;int d=dep[u]-depth;for(int i=19;i>=0;i--)if(d&1<<i)u=fa[i][u];return u;
}
ll dist(int u,int v){return dis[u]+dis[v]-2*dis[LCA(u,v)];
}
struct Node{int x;ll val;Node(int _x=-1,ll _val=0){x=_x,val=_val;}ll operator *(const Node &T)const{if(x==-1||T.x==-1)return -inf;return val+T.val+dist(x,T.x);}
};
struct Data{Node first,second;Data(Node _first=Node(),Node _second=Node()){first=_first,second=_second;}Data operator +(const Data &T)const{ll mx=-inf;pair<Node,Node> res;if(mx<first*second)mx=first*second,res={first,second};if(mx<first*T.first)mx=first*T.first,res={first,T.first};if(mx<first*T.second)mx=first*T.second,res={first,T.second};if(mx<second*T.first)mx=second*T.first,res={second,T.first};if(mx<second*T.second)mx=second*T.second,res={second,T.second};if(mx<T.first*T.second)mx=T.first*T.second,res={T.first,T.second};if(mx==-inf){if(first.x!=-1)return {first,Node()};if(second.x!=-1)return {second,Node()};if(T.first.x!=-1)return {T.first,Node()};if(T.second.x!=-1)return {T.second,Node()};return Data();}return Data(res.first,res.second);}ll operator *(const Data &T)const{return max({first*T.first,first*T.second,second*T.first,second*T.second});} 
};
struct Segment_tree{int num;Data c[M*40];int ls[M*40],rs[M*40];#define mid (l+r>>1)void clear(){num=0;}int New(){int p=++num;c[p]=Data();ls[p]=0,rs[p]=0;return p;}void pushup(int p){if(ls[p]&&rs[p])c[p]=c[ls[p]]+c[rs[p]];else if(ls[p])c[p]=c[ls[p]]; else if(rs[p])c[p]=c[rs[p]]; }void change(int &p,int l,int r,int x,Node v,bool opt=0){if(!p)p=New();if(l==r){c[p].first=v;return ;}if(mid>=x)change(ls[p],l,mid,x,v,opt);else change(rs[p],mid+1,r,x,v,opt);pushup(p);}int merge(int p,int q,int l,int r){if(p==0&&q==0)return 0;if(p==0)return q;if(q==0)return p;if(l==r){c[p]=Data();return p;}ls[p]=merge(ls[p],ls[q],l,mid),rs[p]=merge(rs[p],rs[q],mid+1,r);pushup(p);return p;}#undef mid
}Set;
void clear(){Set.num=0;for(int i=1;i<=n;i++){e[i].clear();insert[i].clear();erase[i].clear();rt[i]=0;}
}
void dfs(int u){st[0][++cnt_dfn]=u;dfn[u]=cnt_dfn;for(auto tmp:e[u]){int v=tmp.first,w=tmp.second;if(v==fa[0][u])continue;fa[0][v]=u;dep[v]=dep[u]+1;dis[v]=dis[u]+w;dfs(v);st[0][++cnt_dfn]=u;}
}
void redfs(int u){for(int idx:insert[u]){int x=u,y=b[idx].x^b[idx].y^u;Node tmp=Node(y,dist(x,y)-2*b[idx].v+dis[x]);Set.change(rt[u],1,m,idx,tmp);}tomax(ans,Set.c[rt[u]].first*Set.c[rt[u]].second-2*dis[u]);for(auto tmp:e[u]){int v=tmp.first,w=tmp.second;if(v==fa[0][u])continue;redfs(v);tomax(ans,Set.c[rt[u]]*Set.c[rt[v]]-2*dis[u]);rt[u]=Set.merge(rt[u],rt[v],1,m);}for(auto idx:erase[u])Set.change(rt[u],1,m,idx,Node(),u==5);}
signed main(){int t;read(t);while(t--){read(n);for(int i=2,u,v,w;i<=n;i++){read(u),read(v),read(w);e[u].push_back({v,w});e[v].push_back({u,w});}read(m);for(int i=1;i<=m;i++)read(b[i].x),read(b[i].y),read(b[i].v);cnt_dfn=0;dfs(1);for(int j=1;j<20;j++)for(int i=1;i+(1<<j)-1<=cnt_dfn;i++){st[j][i]=Min(st[j-1][i],st[j-1][i+(1<<j-1)]);fa[j][i]=fa[j-1][fa[j-1][i]];}for(int i=1,lca,to;i<=m;i++){lca=LCA(b[i].x,b[i].y);if(b[i].x!=lca)insert[b[i].x].push_back(i);if(b[i].y!=lca)insert[b[i].y].push_back(i);to=jump(b[i].x,dep[lca]+1);if(~to)erase[to].push_back(i);to=jump(b[i].y,dep[lca]+1);if(~to)erase[to].push_back(i);}ans=-inf;redfs(1);if(ans==-inf)puts("F");else write(ans>>1),Nxt;clear();}
}
http://www.jsqmd.com/news/815725/

相关文章:

  • 海外发票智能解析:跨版式、多税制票据的自动化处理方案(附GitHub项目地址)
  • 环境配置与基础教程:学习率调度器深度对比:Cosine、Warmup、MultiStep 在 YOLO 训练中的选型策略
  • 从零到一:51单片机驱动NRF24L01实现点对点无线通信全解析
  • Office PPT 批量删除每页相同位置的内容(图片文字等)
  • 2026贵州化妆学校权威推荐榜:正规靠谱机构大盘点,零基础必看 - 深度智识库
  • AI智能体Hermes Agent:闭环学习与多平台部署实战指南
  • 如何在 MATLAB 中调用 OpenAI 兼容 API 连接 Taotoken 多模型服务
  • AnuPpuccin:为Obsidian用户重新定义笔记美学的设计哲学
  • 告别编译焦虑:手把手教你用Buildroot为全志V3S定制最小根文件系统
  • 2026无锡卫生间免砸砖防水、外墙、地下室、楼顶渗漏+彩钢瓦、阳光房隔热 本地专业防水公司TOP5权威推荐(2026年5月本地最新深度调研) - 企业资讯
  • 手把手教你用宝塔面板,30分钟搞定Moodle在线学习平台部署(含SSL配置与数据库避坑)
  • 盒马鲜生卡回收:快速变现攻略及常见问题全解 - 团团收购物卡回收
  • Dify连接器实战:打通AI应用与业务系统的最后一公里
  • 沈阳雨露恒远客运:康平旅游包车怎么联系 - LYL仔仔
  • 太原GEO推广服务核心优势 帮企业打通AI获客新路径 - 奔跑123
  • 2026杭州婚纱照优选|避开132家坑,这9家闭眼选不踩雷 - 江湖评测
  • TQVaultAE深度解析:告别《泰坦之旅》仓库管理烦恼的终极方案
  • 微软5月补丁日深度解析:MDASH AI发现16个高危漏洞,开启智能攻防新纪元
  • 环境配置与基础教程:模型裁剪与加载:只加载部分层预训练权重、冻结骨干网络微调的三种实现方式
  • 温和呵护发丝状态,认准科学营养搭配
  • 10分钟掌握HighwayEnv:自动驾驶强化学习的终极实战指南
  • 3分钟拿回你的QQ聊天记录:全平台数据库密钥提取终极指南
  • iOS 性能监控脚本使用手册:免费工具与最佳实践
  • 2026杭州婚纱照严选报告 128家实地走访 9家靠谱机构直接选 - charlieruizvin
  • 上海湘杰仪器仪表:扬州纸箱抗压强度试验机厂家 - LYL仔仔
  • 2026年AI论文写作工具测评:7款工具横向对比与真实场景选择指南
  • Soot印相提示词失效真相,深度解析Midjourney v6对化学显影语义的底层解析偏差与5种绕过方案
  • 2026年检斤软件深度测评:如何为企业称重匹配最佳方案? - 速递信息
  • 从挤塑板到岩棉板,四川外墙保温材料选型要点与本地厂商全景概览 - 深度智识库
  • 3大核心技巧深度解析QRazyBox:从损坏二维码到完整数据恢复的专业指南