LUOGU P2416 泡芙 (缩点+树剖)
解题思路
首先先缩点,然后将缩完点的权值改成点中路径为1的条数,然后再将边权下放到点权上,求一个每个点到根的路径和,然后用树上2点距离公式算。。刚开始写的线段树,T了2个点。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm> using namespace std;
const int MAXN = ; inline int rd(){
int x=,f=;char ch=getchar();
while(!isdigit(ch)) {f=ch=='-'?:;ch=getchar();}
while(isdigit(ch)) {x=(x<<)+(x<<)+ch-'';ch=getchar();}
return f?x:-x;
} int n,m,head[MAXN],cnt,to[MAXN<<],nxt[MAXN<<],val[MAXN<<],q,xx[MAXN],yy[MAXN],zz[MAXN];
int dfn[MAXN],low[MAXN],stk[MAXN],top,num,col[MAXN],col_num,Sum[MAXN];
int head_[MAXN],to_[MAXN<<],nxt_[MAXN<<],val_[MAXN<<],cnt_;
int fa[MAXN],siz[MAXN],son[MAXN],Top[MAXN],dep[MAXN],w[MAXN];
bool vis[MAXN]; inline void add(int bg,int ed,int w){
to[++cnt]=ed,nxt[cnt]=head[bg],val[cnt]=w,head[bg]=cnt;
} inline void add_(int bg,int ed,int w){
to_[++cnt_]=ed,nxt_[cnt_]=head_[bg],head_[bg]=cnt_,val_[cnt_]=w;
} void tarjan(int x,int f){
dfn[x]=low[x]=++num;stk[++top]=x;vis[x]=;int u;
for(register int i=head[x];i;i=nxt[i]){
u=to[i];if(u==f) continue;
if(!dfn[u]) tarjan(u,x),low[x]=min(low[x],low[u]);
else if(vis[u]) low[x]=min(low[x],dfn[u]);
}
if(low[x]==dfn[x]) {
col[x]=++col_num;vis[x]=;
while(stk[top]!=x) {col[stk[top]]=col_num;vis[stk[top--]]=;}
top--;
}
} void dfs1(int x,int f,int d){
dep[x]=d,fa[x]=f,siz[x]=;
int maxson=-,u;
for(register int i=head_[x];i;i=nxt_[i]){
u=to_[i];if(u==f) continue;
Sum[u]=Sum[x]+w[u]+val_[i];
dfs1(u,x,d+);siz[x]+=siz[u];
if(siz[u]>maxson) {maxson=siz[u];son[x]=u;}
}
} void dfs2(int x,int topf){
Top[x]=topf;
if(!son[x]) return;dfs2(son[x],topf);int u;
for(register int i=head_[x];i;i=nxt_[i]){
u=to_[i];if(u==son[x] || u==fa[x]) continue;
dfs2(u,u);
}
} int lca(int x,int y){
while(Top[x]!=Top[y]) {
if(dep[Top[x]]<dep[Top[y]]) swap(x,y);
x=fa[Top[x]];
}
return dep[x]>dep[y]?y:x;
} int main(){
n=rd(),m=rd();int x,y;
for(register int i=;i<=m;i++){
xx[i]=rd(),yy[i]=rd(),zz[i]=rd();
add(xx[i],yy[i],zz[i]),add(yy[i],xx[i],zz[i]);
}tarjan(,);num=;
for(register int i=;i<=m;i++) {
if(col[xx[i]]==col[yy[i]]) w[col[xx[i]]]+=zz[i];
else add_(col[xx[i]],col[yy[i]],zz[i]),add_(col[yy[i]],col[xx[i]],zz[i]);
}
Sum[]=w[];
dfs1(,,);dfs2(,);q=rd();int Lca;
while(q--){
x=rd(),y=rd();Lca=lca(col[x],col[y]);
// cout<<Sum[col[x]]<<" "<<Sum[col[y]]<<" "<<Sum[Lca]<<endl;
puts(((Sum[col[x]]+Sum[col[y]]-*Sum[Lca]+w[Lca])==)?"NO":"YES");
}
return ;
}
LUOGU P2416 泡芙 (缩点+树剖)的更多相关文章
- CF487E Tourists - Tarjan缩点 + 树剖 + multiset
Solution 先Tarjan求出点双联通分量 并缩点. 用$multiset$维护 点双内的最小点权. 容易发现, 点双内的最小点权必须包括与它相连的割边的点权. 所以我们必须想办法来维护. 所以 ...
- poj3694 Network[边双缩点+树剖/并查集]
首先同一个点双内部的加边肯定不影响..所以先缩点成树,然后每次加一条边,这条对应的树上路径上所有边就都不是桥了,且每次操作独立作用,不相互影响(不过有可能本来一条边已经不是桥了又被标记了一次),所以每 ...
- LUOGU P1967 货车运输(最大生成树+树剖+线段树)
传送门 解题思路 货车所走的路径一定是最大生成树上的路径,所以先跑一个最大生成树,之后就是求一条路径上的最小值,用树剖+线段树,注意图可能不连通.将边权下放到点权上,但x,y路径上的lca的答案不能算 ...
- SCOI2016幸运数字(树剖/倍增/点分治+线性基)
题目链接 loj luogu 题意 求树上路径最大点权异或和 自然想到(维护树上路径)+ (维护最大异或和) 那么有三种方法可以选择 1.树剖+线性基 2.倍增+线性基 3.点分治+线性基 至于线性基 ...
- 洛谷P4332 [SHOI2014]三叉神经树(LCT,树剖,二分查找,拓扑排序)
洛谷题目传送门 你谷无题解于是来补一发 随便百度题解,发现了不少诸如树剖\(log^3\)LCT\(log^2\)的可怕描述...... 于是来想想怎么利用题目的性质,把复杂度降下来. 首先,每个点的 ...
- [SDOI2016]游戏 树剖+李超树
目录 链接 思路 update 代码 链接 https://www.luogu.org/problemnew/show/P4069 思路 树剖+超哥线段树 我已经自毙了,自闭了!!!! update ...
- P2486 [SDOI2011]染色(树剖)区间覆盖+区间的连续段
https://www.luogu.org/problemnew/show/P2486 值的一看https://www.cnblogs.com/Tony-Double-Sky/p/9283262.ht ...
- 洛谷P4719 动态DP —— 动态DP(树剖+矩乘)
题目:https://www.luogu.org/problemnew/show/P4719 感觉这篇博客写得挺好:https://blog.csdn.net/litble/article/detai ...
- CF487E Tourists【圆方树+tarjan+multiset+树剖+线段树】
圆方树不仅能解决仙人掌问题(虽然我仙人掌问题也没用过圆方树都是瞎搞过去的),还可以解决一般图的问题 一般图问题在于缩完环不是一棵树,所以就缩点双(包括双向边) 每个方点存他所在点双内除根以外的点的最小 ...
随机推荐
- idea中选中了一个变量名,会高亮显示位于别的地方的这个变量名,那么怎么修改其他地方的高亮颜色
- [21]APUE:线程同步之记录锁(文件)
[a] 概念 建议锁:在遵循相同记录锁规则的进程/线程间生效,通常用于保证某个程序自身多个进程/线程间的数据一致性 强制锁:意在保证所有进程间的数据一致性,但不一定有效:如不能应对先 unlink 后 ...
- ## jvm知识点零碎整理
1.初始化VM options配置 idea安装目录\bin\idea.exe.vmoptions 和 idea64.exe.vmoptions可以看到初始配置: -Xms128m (设置初始化堆内 ...
- 初探.Net Core API 网关Ocelot(一)
一.介绍 Ocelot 是基于.NetCore实现的开源的API网关,支持IdentityServer认证.Ocelot具有路由.请求聚合.服务发现.认证.鉴权.限流熔断等功能,并内置了负载均衡器与S ...
- 论文阅读笔记---ShuffleNet V1
01 ShuffleNet V1要解决什么问题 为算力有限的嵌入式场景下专门设计一个高效的神经网络架构. 02 亮点 使用了两个新的操作:pointwise group convolution和cha ...
- JS事件 鼠标经过事件(onmouseover)鼠标经过事件,当鼠标移到一个对象上时,该对象就触发onmouseover事件,并执行onmouseover事件调用的程序。
鼠标经过事件(onmouseover) 鼠标经过事件,当鼠标移到一个对象上时,该对象就触发onmouseover事件,并执行onmouseover事件调用的程序. 现实鼠标经过"确定&quo ...
- 服务启动脚本start_boot.sh
vim start_boot.sh #!/bin/bash usage(){ echo "$0 [start|stop|usage]" } status_springboot(){ ...
- Java Queue队列
前言 Queue队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作,LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用. ...
- php相关操作
array_unshift : 数组头部追加 用法如下: $arr = ['demo','dmoa']; array_unshift($arr,'demob'); //在$arr的前面追加demob ...
- [JZOJ3347] 【NOI2013模拟】树的难题
题目 题目大意 给你一棵树,每个节点有三种黑.白.灰三种颜色. 你要割掉一些边(每条边被割需要付出一定的代价),使得森林的每棵树满足: 没有黑点或至多一个白点. 思考历程 这题一看就知道是一个树形DP ...