P4320-道路相遇,P5058-[ZJOI2004]嗅探器【圆方树,LCA】
两题差不多就一起写了
P4320-道路相遇
题目链接:https://www.luogu.com.cn/problem/P4320
题目大意
\(n\)个点\(m\)条边的一张图,\(q\)次询问两个点之间路径的必经点数量。
解题思路
建出圆方树然后问题就变为询问两个点之间路径的圆点数量,可以直接倍增\(LCA\)求。当然还有更方便的,因为这两个点是圆点,它们的路径一定是一圆一方,所以答案就是它们直接的路径长度\(len/2+1\)。也是倍增或者树剖\(LCA\)就好了。
时间复杂度\(O(n\log n)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int N=1e6+10,T=20;
int n,m,t,dfc,dfn[N],low[N];
int dep[N],f[N][T+1];
vector<int> G[N],H[N];
stack<int> s;
void tarjan(int x){
dfn[x]=low[x]=++dfc;
s.push(x);
for(int y:G[x])
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
if(low[y]==dfn[x]){
int k;++n;
do{
k=s.top();s.pop();
H[n].push_back(k);
H[k].push_back(n);
}while(k!=y);
H[n].push_back(x);
H[x].push_back(n);
}
}
else low[x]=min(low[x],dfn[y]);
return;
}
void dfs(int x,int fa){
dep[x]=dep[fa]+1;
for(int y:H[x]){
if(y==fa)continue;
dfs(y,x);f[y][0]=x;
}
return;
}
int LCA(int x,int y){
if(dep[x]>dep[y])swap(x,y);
for(int i=T;i>=0;i--)
if(dep[f[y][i]]>=dep[x])
y=f[y][i];
if(x==y)return x;
for(int i=T;i>=0;i--)
if(f[x][i]!=f[y][i])
x=f[x][i],y=f[y][i];
return f[x][0];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
tarjan(1);dfs(1,0);
for(int j=1;j<=T;j++)
for(int i=1;i<=n;i++)
f[i][j]=f[f[i][j-1]][j-1];
scanf("%d",&t);
while(t--){
int x,y,p;
scanf("%d%d",&x,&y);
p=LCA(x,y);
printf("%d\n",(dep[x]+dep[y]-2*dep[p])/2+1);
}
return 0;
}
P5058-[ZJOI2004]嗅探器
题目链接:https://www.luogu.com.cn/problem/P5058
题目大意
一张\(n\)个点\(m\)条边的无向图,给出两个点求它们之间编号最小的必经点。
解题思路
一组询问所以直接建好圆方树\(dfs\)就好了,如果多组询问的话也可以做,倍增维护树链最小值就好了。
这题是一组询问所以随便写\(O(n)\)
code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
const int N=4e5+10;
int n,m,dfc,cnt,s,t,dfn[N],low[N];
vector<int> G[N],H[N];
stack<int> S;
void tarjan(int x){
dfn[x]=low[x]=++dfc;
S.push(x);
for(int y:G[x])
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
if(low[y]==dfn[x]){
int k;++cnt;
do{
k=S.top();S.pop();
H[cnt].push_back(k);
H[k].push_back(cnt);
}while(k!=y);
H[cnt].push_back(x);
H[x].push_back(cnt);
}
}
else low[x]=min(low[x],dfn[y]);
return;
}
int dfs(int x,int fa){
int k;
if(x==t)return n+1;
for(int y:H[x]){
if(y==fa)continue;
if(k=dfs(y,x))
return min((x==s)?(n+1):x,k);
}
return 0;
}
int main()
{
scanf("%d",&n);cnt=n;
while(1){
int x,y;
scanf("%d%d",&x,&y);
if(!x&&!y)break;
G[x].push_back(y);
G[y].push_back(x);
}
for(int i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
scanf("%d%d",&s,&t);
s=dfs(s,0);
if(s>n||!s)printf("No solution\n");
else printf("%d\n",s);
return 0;
}
P4320-道路相遇,P5058-[ZJOI2004]嗅探器【圆方树,LCA】的更多相关文章
- 【luogu4320】道路相遇 (圆方树 + LCA)
Description 给你一张\(~n~\)个点\(~m~\)条边的无向图,保证无重边无自环, 共\(~q~\)组询问求\(~x~\)到\(~y~\)的路径上必经的点数. Solution ...
- Traffic Real Time Query System 圆方树+LCA
题目描述 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, ...
- 【洛谷 P4320】 道路相遇 (圆方树,LCA)
题目链接 题意:给一张无向图和\(M\)个询问,问\(u,v\)之间的路径的必经之点的个数. 对图建出圆方树,然后必经之点就是两点路径经过的原点个数,用\((dep[u]+dep[v]-dep[LCA ...
- luoguP4320 道路相遇 圆方树
标题已经告诉你怎么做了..... 两点间的圆点个数即为所求 建出圆方树后打个树剖求$lca$就行..... 复杂度$O(n + q \log n)$ #include <cstdio> # ...
- 【刷题】洛谷 P4320 道路相遇
题目描述 在 H 国的小 w 决定到从城市 \(u\) 到城市 \(v\) 旅行,但是此时小 c 由于各种原因不在城市 \(u\),但是小 c 决定到在中途与小 w 相遇 由于 H 国道路的原因,小 ...
- 图论杂项细节梳理&模板(虚树,圆方树,仙人掌,欧拉路径,还有。。。)
orzYCB 虚树 %自为风月马前卒巨佬% 用于优化一类树形DP问题. 当状态转移只和树中的某些关键点有关的时候,我们把这些点和它们两两之间的LCA弄出来,以点的祖孙关系连成一棵新的树,这就是虚树. ...
- 仙人掌&圆方树
仙人掌&圆方树 Tags:图论 [x] [luogu4320]道路相遇 https://www.luogu.org/problemnew/show/P4320 [ ] [SDOI2018]战略 ...
- Note -「圆方树」学习笔记
目录 圆方树的定义 圆方树的构造 实现 细节 圆方树的运用 「BZOJ 3331」压力 「洛谷 P4320」道路相遇 「APIO 2018」「洛谷 P4630」铁人两项 「CF 487E」Touris ...
- [SDOI2018]战略游戏 圆方树,树链剖分
[SDOI2018]战略游戏 这题是道路相遇(题解)的升级版,询问的两个点变成了\(S\)个点. LG传送门 还是先建出圆方树,考虑对于询问的\(S\)个点,答案就是圆方树上能包含这些点的最小连通块中 ...
随机推荐
- docker harbor安装
# 官网下载离线包,https://github.com/goharbor/harbor/releases src]# tar xf harbor-offline-installer-v1.8.3.t ...
- SpringBoot整合mybatis快速入门
一.创建一个SpringBoot项目 二.引入相关依赖 <!--web核心依赖--> <dependency> <groupId>o ...
- js中使用function定义类、实例化,函数的调用方法
function Test002(name, age){ name, age, this.printInfo = function(){ //定义的公有方法 console.log(name, age ...
- Windows10 Dev - Background Execution
The Universal Windows Platform (UWP) introduces new mechanisms, which allow the applications to perf ...
- spring知识点(面试题)
转自(参考):https://baijiahao.baidu.com/s?id=1595722523154435312&wfr=spider&for=pc 本人收集了一些在大家在面试时 ...
- 从新建文件夹开始构建ShadowPlay Engine(5)
本篇序言 从本篇开始,我们要开始构建引擎核心中的系统组件部分,广义上讲其实我们从开始到现在一直都是在构建引擎核心中的系统部分,但严格的定义中系统组件大概有这么几个:内存管理,线程管理,文件管理,时间系 ...
- 关闭 Scroll Lock
通常,在电子表格中选择一个单元格并按箭头键时,所选内容会在各个单元格之间上下左右移动,具体取决于您按的箭头键.但是,如果在 Scroll Lock 处于开启状态时按箭头键,则向上或向下滚动一行.或者, ...
- golang 模板 html/template与text/template
html模板生成: html/template包实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出.它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用t ...
- JMeter中使用交替控制器设置循环次数后都执行一次?
JMeter在线程组设置循环3次,执行后只执行了一次就停止执行了 排查原因:线程组下添加了一些请求信息(HTTP Cache Manager.HTTP Cookie Manager.HTTP Requ ...
- MyBatis学习总结(六)——Mybatis3.x与Spring4.x整合
一.搭建开发环境 1.1.使用Maven创建Web项目 执行如下命令: mvn archetype:create -DgroupId=me.gacl -DartifactId=spring4-myba ...