【Targan+LCA】HDU 3686 Traffic Real Time Query
题目内容
洛谷链接
给出一个\(n\)个节点,\(m\)条边的无向图和两个节点\(s\)和\(t\),问这两个节点的路径中有几个点必须经过。
输入格式
第一行是\(n\)和\(m\)。
接下来\(m\)行,给出两个数表示这两个节点之间存在一条边。
接下来一行一个整数\(Q\),表示询问个数。
接下来\(Q\)行,每行两个整数\(s\)和\(t\)(\(s\not= t\))。
数据范围
\(0<n\le 10000,0<m\le 100000,0<Q\le 10000,0<s,t\le m\)
输出格式
对于每个询问,输出一行表示答案
样例输入
5 6
1 2
1 3
2 3
3 4
4 5
3 5
2
2 3
2 4
0 0
样例输出
0
1
思路
这个题问的就是\(s\)到\(t\)路径上割点的个数。
点双缩点,可以知道,每条边仅在一个联通块中,把割点和它相邻的联通块建边,从而构造棵树。
询问\(s\)边和\(t\)边,需要求它们分别属于哪个连通块。所以问题转化成了一棵树中,有些点已标记为割点,询问两个非割点之间路径上有多少个割点。
因此选择一个点作为树根,求出每个点到树根路径上有多少个割点,然后对于询问的两个点求一次LCA即可。
代码
#include<cstdio>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn=10000+10;
const int maxm=100000+10;
struct Edge{
int u,to,next,vis,id;
}edge[maxm<<1];
int head[maxn<<1],dfn[maxn<<1],low[maxn],st[maxm],iscut[maxn],subnet[maxn],bian[maxm];
int cnt,time,top,btot;
vector<int> belong[maxn];
void add(int u,int to){
edge[cnt].u=u;
edge[cnt].to=to;
edge[cnt].next=head[u];
edge[cnt].vis=0;
head[u]=cnt++;
}
void init(int n){
for(int i=0;i<=n;i++){
head[i]=-1;
dfn[i]=iscut[i]=subnet[i]=0;
belong[i].clear();
}
cnt=time=top=btot=0;
}
void dfs(int u){
dfn[u]=low[u]=++time;
for(int i=head[u];i!=-1;i=edge[i].next){
if(edge[i].vis)continue;
edge[i].vis=edge[i^1].vis=1;
int to=edge[i].to;
st[++top]=i;
if(!dfn[to]){
dfs(to);
low[u]=min(low[u],low[to]);
if(dfn[u]<=low[to]){
subnet[u]++;
iscut[u]=1;
btot++;
do{
int now=st[top--];
belong[edge[now].u].push_back(btot);
belong[edge[now].to].push_back(btot);
bian[edge[now].id]=btot;
to=edge[now].u;
}while(to!=u);
}
}
else
low[u]=min(low[u],low[to]);
}
}
int B[maxn<<2],F[maxn<<2],d[maxn<<2][20],pos[maxn<<2],tot,dep[maxn<<1];
bool treecut[maxn<<1];
void RMQ1(int n){
for(int i=1;i<=n;i++)d[i][0]=B[i];
for(int j=1;(1<<j)<=n;j++)
for(int i=1;i+j-1<=n;i++)
d[i][j]=min(d[i][j-1],d[i + (1<<(j-1))][j-1]);
}
int RMQ(int L,int R){
int k=0;
while((1<<(k+1))<=R-L+1) k++;
return min(d[L][k],d[R-(1<<k)+1][k] );
}
int lca(int a,int b){
if(pos[a] > pos[b])swap(a,b);
int ans=RMQ(pos[a],pos[b]);
return F[ans];
}
//写了个RMQ求LCA
void DFS(int u){
dfn[u]=++time;
B[++tot]=dfn[u];
F[time]=u;
pos[u]=tot;
for(int i=head[u];i!=-1;i=edge[i].next){
int to=edge[i].to;
if(!dfn[to]){
if(treecut[u])
dep[to]=dep[u] + 1;
else
dep[to]=dep[u];
DFS(to);
B[++tot]=dfn[u];
}
}
}
void solve(int n){
for(int i=0;i<=n;i++) {
dfn[i]=0;
}
time=tot=0;
for(int i=1;i<=n;i++)
if(!dfn[i]){
dep[i]=0;
DFS(i);
}
RMQ1(tot);
int m,u,to;
scanf("%d",&m);
while(m--){
scanf("%d%d",&u,&to);
u=bian[u];to=bian[to];
if(u<0||to<0){
printf("0\n");continue;
}
int LCA=lca(u,to);
if(u==LCA)
printf("%d\n",dep[to]-dep[u]-treecut[u]);
else if(to == LCA)
printf("%d\n",dep[u]-dep[to]-treecut[to]);
else
printf("%d\n",dep[u]+dep[to]-2*dep[LCA]-treecut[LCA]);
}
}
int main(){
int n,m,u,to;
while(scanf("%d%d",&n,&m)!=-1 && n){
init(n);
for(int i=1;i<=m;i++){
scanf("%d%d",&u,&to);
edge[cnt].id=i;
add(u,to);
edge[cnt].id=i;
add(to,u);
}
for(int i=1;i<=n;i++)
if(!dfn[i]){
dfs(i);
subnet[i]--;
if(subnet[i]<=0)iscut[i]=0;
}
int ditot=btot;
for(int i=1;i<=btot;i++)
treecut[i]=0;
for(int i=1;i<=btot+n;i++)
head[i]=-1;
cnt=0;
for(int i=1;i<=n;i++)
if(iscut[i]){
sort(belong[i].begin(),belong[i].end());
ditot++;
treecut[ditot]=1;
add(belong[i][0],ditot);
add(ditot,belong[i][0]);
for(int j=1;j<belong[i].size();j++)
if(belong[i][j]!=belong[i][j-1]){
add(belong[i][j],ditot);
add(ditot,belong[i][j]);
}
}
solve(ditot);
}
return 0;
}
【Targan+LCA】HDU 3686 Traffic Real Time Query的更多相关文章
- HDU 3686 Traffic Real Time Query System (图论)
HDU 3686 Traffic Real Time Query System 题目大意 给一个N个点M条边的无向图,然后有Q个询问X,Y,问第X边到第Y边必需要经过的点有多少个. solution ...
- hdu 3686 Traffic Real Time Query System 点双两通分量 + LCA。这题有重边!!!
http://acm.hdu.edu.cn/showproblem.php?pid=3686 我要把这题记录下来. 一直wa. 自己生成数据都是AC的.现在还是wa.留坑. 我感觉我现在倒下去床上就能 ...
- HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)
Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...
- HDU 3686 Traffic Real Time Query System(点双连通)
题意 给定一张 \(n\) 个点 \(m\) 条边的无向图,\(q\) 次询问,每次询问两边之间的必经之点个数. 思路 求两点之间必经之边的个数用的是边双缩点,再求树上距离.而对比边双和点双之 ...
- 【刷题】HDU 5869 Different GCD Subarray Query
Problem Description This is a simple problem. The teacher gives Bob a list of problems about GCD (Gr ...
- 【线段树】HDU 5493 Queue (2015 ACM/ICPC Asia Regional Hefei Online)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5493 题目大意: N个人,每个人有一个唯一的高度h,还有一个排名r,表示它前面或后面比它高的人的个数 ...
- 【归并排序】【逆序数】HDU 5775 Bubble Sort
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5775 题目大意: 冒泡排序的规则如下,一开始给定1~n的一个排列,求每个数字在排序过程中出现的最远端 ...
- 【线段树】HDU 5443 The Water Problem
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5443 题目大意: T组数据.n个值,m个询问,求区间l到r里的最大值.(n,m<=1000) ...
- 【刷题】HDU 2222 Keywords Search
Problem Description In the modern time, Search engine came into the life of everybody like Google, B ...
随机推荐
- 提交并发量的方法:Java GC tuning :Garbage collector
三色算法,高效率垃圾回收,jvm调优 Garbage collector:垃圾回收器 What garbage? 没有任何引用指向它的对象 JVM GC回收算法: 引用计数法(ReferenceCou ...
- Docker 学习笔记一
Docker 学习笔记一 1.Docker是什么? Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源.让开发者打包他们的应用以及依赖包到一 ...
- docker下部署jira破解版
1. 制作Docker破解容器 在/opt/jira下新建一个Dockerfile文件 touch Dockerfile 编辑Dockerfile文件 vim Dockerfile FROM cpta ...
- 什么是 Catalan 数列以及其应用
引言 在开始论述之前,我想请大家先看下这几个问题: 有 \(2n\) 个人排成一行进入剧场.入场费 5 元.其中只有 \(n\) 个人有一张 5 元钞票,另外 \(n\) 人只有 10 元钞票,剧院无 ...
- 中科蓝讯530X、532X模块之硬件UART
文章转载请注明来源 作者:Zeroer 一.选择IO 想要使用硬件的UART必须先确定要mapping的pin脚 注意:用作TX的脚位可以分时复用成单线双工 因为芯片默认的调试串口用的是UART0,所 ...
- 微信小程序问题汇总
一.消息推送配置 1.解析失败.请检查信息是否填写正确 服务器地址中不能使用其他的端口号,把端口号去掉,默认就是走80或443端口,另外这个地址需要外网访问,我使用了nat123映射了80端口,这个工 ...
- 白话ansible-runner--1.环境搭建
最近在Windows10上的项目需要使用到ansible API调用,参考 本末大神 推荐ansible API用官网封装的ansible-runner开发比较友好,ansible-runner是an ...
- el-table行点击事件row-click与列按钮事件冲突
需求简述 表格用el-table实现,操作列的编辑按钮点击事件正常实现.现要为行加一点击事件,即row-click.加上后,发现点击操作列的编辑按钮时,会触发按钮本身事件,同时会触发行点击事件.第一版 ...
- vsCode 搭建Java开发环境
1.安装扩展 Java Extension Pack Spring Boot Extension Pack 2.配置Maven 打开设置 搜索maven 找到并打开 在 settings.json ...
- 极简 Node.js 入门 - 4.3 可读流
极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...