题目内容

洛谷链接

给出一个\(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的更多相关文章

  1. HDU 3686 Traffic Real Time Query System (图论)

    HDU 3686 Traffic Real Time Query System 题目大意 给一个N个点M条边的无向图,然后有Q个询问X,Y,问第X边到第Y边必需要经过的点有多少个. solution ...

  2. hdu 3686 Traffic Real Time Query System 点双两通分量 + LCA。这题有重边!!!

    http://acm.hdu.edu.cn/showproblem.php?pid=3686 我要把这题记录下来. 一直wa. 自己生成数据都是AC的.现在还是wa.留坑. 我感觉我现在倒下去床上就能 ...

  3. 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 ...

  4. HDU 3686 Traffic Real Time Query System(点双连通)

    题意 ​ 给定一张 \(n\) 个点 \(m\) 条边的无向图,\(q\) 次询问,每次询问两边之间的必经之点个数. 思路 ​ 求两点之间必经之边的个数用的是边双缩点,再求树上距离.而对比边双和点双之 ...

  5. 【刷题】HDU 5869 Different GCD Subarray Query

    Problem Description This is a simple problem. The teacher gives Bob a list of problems about GCD (Gr ...

  6. 【线段树】HDU 5493 Queue (2015 ACM/ICPC Asia Regional Hefei Online)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5493 题目大意: N个人,每个人有一个唯一的高度h,还有一个排名r,表示它前面或后面比它高的人的个数 ...

  7. 【归并排序】【逆序数】HDU 5775 Bubble Sort

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5775 题目大意: 冒泡排序的规则如下,一开始给定1~n的一个排列,求每个数字在排序过程中出现的最远端 ...

  8. 【线段树】HDU 5443 The Water Problem

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5443 题目大意: T组数据.n个值,m个询问,求区间l到r里的最大值.(n,m<=1000) ...

  9. 【刷题】HDU 2222 Keywords Search

    Problem Description In the modern time, Search engine came into the life of everybody like Google, B ...

随机推荐

  1. pytest封神之路第二步 132个命令行参数用法

    在Shell执行pytest -h可以看到pytest的命令行参数有这10大类,共132个 序号 类别 中文名 包含命令行参数数量 1 positional arguments 形参 1 2 gene ...

  2. 不用写代码也能做表单 —— 加载meta即可

    做增删改查要写多少代码? 一个表单一套代码,十个表单十套代码吗? 我这么懒,怎么会写这么多代码? 我想做到:即使一百个表单也只需要一套代码(而且不需要复制粘贴).实现多个表单,只需要加载不同的meta ...

  3. 还不懂Redis?看完这个故事就明白了!

    我是Redis 你好,我是Redis,一个叫Antirez的男人把我带到了这个世界上. 说起我的诞生,跟关系数据库MySQL还挺有渊源的. 在我还没来到这个世界上的时候,MySQL过的很辛苦,互联网发 ...

  4. Java链接db2套接字出错

    ### Error querying database. Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Could ...

  5. python中使用cookie进行模拟登录

    背景:使用cookie模拟登录豆瓣->我的豆瓣网页 [准备工作] 1.通过Fiddler抓取“我的豆瓣”url: 2.通过Fiddler抓取“我的豆瓣”cookie值. import urlli ...

  6. 居然仅用浏览器,就完成了Spring Boot应用的开发与部署!

    最近有幸试用了一下阿里云的一个新产品:云开发平台,体验一把全新的开发模式!虽然中间也碰到了一些问题,但整体的体验透露着未来感,因为整个过程都不需要使用我们最常用的IDEA,仅依靠浏览器就把一个Spri ...

  7. 蒲公英 · JELLY技术周刊 Vol.22: npm i react-router@6.0.0-beta.0

    蒲公英 · JELLY技术周刊 Vol.22 近期 React Router 已经释出了 6.x 的 beta 版本,正式版本已经不远了,作为 React 生态中的重要组成部分,React Route ...

  8. 深度长文整理-Redis进阶

    目录 一.基础 二.为什么Redis是单线程的? 三.为什么单线程这么快? 四.select.poll.epoll 五.Redis的事物 六.Redis的监控 七.Redis的配置文件 八.Redis ...

  9. netty之handler write

    转载自:https://blog.csdn.net/FishSeeker/article/details/78447684 实验过,例如channle的handler里有很多个outhandler,在 ...

  10. react项目创建流程

    react 项目搭建 系统: windows 1.安装 node node 下载地址.一路 next 如果遇到 windows 没有权限安装 msi 文件.打开 cmd,运行msiexec /pack ...