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\)个点,答案就是圆方树上能包含这些点的最小连通块中 ...
随机推荐
- pyspark默认使用python2-----更改
默认使用的竟然是2.7好烦如何解决呢 配置环境变量就行了 vi ~/.bashrc 添加一句话 export PATH=/home/hadoop/app/python3/bin:$PATH 保存退出 ...
- 通过PEB的Ldr枚举进程内所有已加载的模块
一.几个重要的数据结构,可以通过windbg的dt命令查看其详细信息 _PEB._PEB_LDR_DATA._LDR_DATA_TABLE_ENTRY 二.技术原理 1.通过fs:[30h]获取当前进 ...
- Failed to start LSB: Bring up/down错误解决方法
很多朋友在使用centos7系统时,有时候需要分配多个IP地址,这就涉及到修改网卡配置,但是在修改完网卡配置时,重启网络服务时会出现"Failed to start LSB: Bring u ...
- String与Int类型的转换
http://blog.sina.com.cn/s/blog_4f9d6b1001000bfo.html int -> String int i=12345; String s="&q ...
- rabbitMq接收实体
- jdbc操作mysql(一)
java.sql包 在使用jdbc之前,我们先看看有关操作jdbc会用到的几个类和接口,通过查看官方文档可知 DriverManager:用于管理一组JDBC驱动程序的基本服务,即管理数据库中的所有驱 ...
- Spring Boot +Vue 项目实战笔记(三):数据库的引入
这一篇的主要内容是引入数据库并实现通过数据库验证用户名与密码. 一.引入数据库 之前说过数据库的采用是 MySQL,算是比较主流的选择,从性能和体量等方面都比较优秀,当然也有一些弊端,但数据库不是我们 ...
- SSD算法原理
Paper: https://arxiv.org/pdf/1512.02325.pdf SSD用神经网络(VGG)提取多层feature map ,来实现对不同大小物体的检测.如下图所示: We us ...
- 日常shell练习
2021-07-19 1.echo的使用 1.1 echo -n 表示不换行输出 # echo输出会自动换行,换行输出两个1 echo 1 echo 1 # 不换行输出,不换行输出两个1 echo - ...
- 根据短链生成二维码并上传七牛云(Java)
通过短链生成二维码并上传七牛云(Java) 前言 网上这种帖子其实也是很多,大部分搜出来的是CSDN的,然后点进去一看都几乎一样:所以这次给个自己实践的例子记录. 这次也是通过搜索得到的一部分能实现这 ...