题目大意:

  有一张无向连通图,问从一条边走到另一条边必定要经过的点有几个。

思路:

  先用tarjan将双连通分量都并起来,剩下的再将割点独立出来,建成一棵树,之后记录每个点到根有几个割点,再用RMQ求LCA计算。

  注意:数组范围。

代码:

 #include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=,M=;
int u[M<<],v[M<<],nex[M<<],id[M<<],hea[N<<],dfn[N<<],low[N],st[M],sub[N],edge[M],
fa[N<<][],f[N<<],pos[N<<],dep[N<<];
bool vis[M<<],iscut[N],treecut[N<<];
int tim,top,tot,cnt,num;
vector <int> belo[N]; int read()
{
int x=; char ch=getchar();
while (ch<'' || ch>'') ch=getchar();
while (ch>='' && ch<='') x=(x<<)+(x<<)+ch-,ch=getchar();
return x;
} void add(int x,int y) { v[cnt]=y,u[cnt]=x,nex[cnt]=hea[x],vis[cnt]=,hea[x]=cnt++; } void tarjan(int x)
{
dfn[x]=low[x]=++tim;
for (int i=hea[x];~i;i=nex[i])
if (!vis[i])
{
int y=v[i]; st[++top]=i;
vis[i]=vis[i^]=;
if (!dfn[y])
{
tarjan(y);
low[x]=min(low[x],low[y]);
if (low[y]>=dfn[x])
{
++sub[x],++num;
iscut[x]=;
do
{
int now=st[top--];
belo[u[now]].push_back(num);
belo[v[now]].push_back(num);
edge[id[now]]=num;
y=u[now];
}while (y^x);
}
}
else low[x]=min(low[x],dfn[y]);
}
} void dfs(int x)
{
dfn[x]=++tim; fa[++tot][]=dfn[x];
f[tim]=x; pos[x]=tot;
for (int i=hea[x];~i;i=nex[i])
{
int y=v[i];
if (!dfn[y])
{
dep[y]=dep[x]+treecut[x];
dfs(y); fa[++tot][]=dfn[x];
}
}
} void RMQ(int n)
{
for (int j=;(<<j)<=n;++j)
for (int i=;i+j-<=n;++i)
fa[i][j]=min(fa[i][j-],fa[i+(<<j-)][j-]);
} int lca(int x,int y)
{
if (pos[x]<pos[y]) swap(x,y);
int k=;
while (<<(k+)<=pos[x]-pos[y]+) ++k;
return f[min(fa[pos[y]][k],fa[pos[x]-(<<k)+][k])];
} void wk(int n)
{
int i,m,x,y;
for (tim=tot=i=;i<=n;++i) dfn[i]=;
for (i=;i<=n;++i)
if (!dfn[i]) dep[i]=,dfs(i);
RMQ(tot);
for (m=read();m--;)
{
x=edge[read()],y=edge[read()];
if (x< || y<) { puts(""); continue; }
int z=lca(x,y);
if (x==z) printf("%d\n",dep[y]-dep[x]-treecut[x]);
else if (y==z) printf("%d\n",dep[x]-dep[y]-treecut[y]);
else printf("%d\n",dep[x]+dep[y]-(dep[z]<<)-treecut[z]);
}
} int main()
{
int n,m;
while (~scanf("%d%d",&n,&m))
{
int i; cnt=top=num=tim=;
if (!(n+m)) break;
for (i=;i<=n;++i) hea[i]=-,dfn[i]=sub[i]=iscut[i]=,belo[i].clear();
for (i=;i<=m;++i)
{
int x=read(),y=read();
id[cnt]=i,add(x,y),id[cnt]=i,add(y,x);
}
for (i=;i<=n;++i)
if (!dfn[i])
{
tarjan(i);
if (--sub[i]<=) iscut[i]=;
}
for (i=;i<=num;++i) treecut[i]=;
for (i=;i<=num+n;++i) hea[i]=-;
cnt=;
for (i=;i<=n;++i)
if (iscut[i])
{
sort(belo[i].begin(),belo[i].end());
treecut[++num]=;
add(belo[i][],num),add(num,belo[i][]);
for (int j=;j<belo[i].size();++j)
if (belo[i][j]^belo[i][j-]) add(belo[i][j],num),add(num,belo[i][j]);
}
wk(num);
}
return ;
}

UVALive-4839 HDU-3686 Traffic Real Time Query System 题解的更多相关文章

  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)(2010 Asia Hangzhou Regional Contest)

    Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...

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

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

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

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

  5. HDU3686 Traffic Real Time Query System 题解

    题目 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, t ...

  6. 【Targan+LCA】HDU 3686 Traffic Real Time Query

    题目内容 洛谷链接 给出一个\(n\)个节点,\(m\)条边的无向图和两个节点\(s\)和\(t\),问这两个节点的路径中有几个点必须经过. 输入格式 第一行是\(n\)和\(m\). 接下来\(m\ ...

  7. 【HDOJ】3686 Traffic Real Time Query System

    这题做了几个小时,基本思路肯定是求两点路径中的割点数目,思路是tarjan缩点,然后以割点和连通块作为新节点见图.转化为lca求解.结合点——双连通分量与LCA. /* 3686 */ #includ ...

  8. CH#24C 逃不掉的路 和 HDU3686 Traffic Real Time Query System

    逃不掉的路 CH Round #24 - 三体杯 Round #1 题目描述 现代社会,路是必不可少的.任意两个城镇都有路相连,而且往往不止一条.但有些路连年被各种XXOO,走着很不爽.按理说条条大路 ...

  9. Traffic Real Time Query System 圆方树+LCA

    题目描述 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, ...

随机推荐

  1. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  2. javascript中的变量

    变量 var x = 0; 这是声明了一个变量的实例,我们可以把变量看做存储数据的容器.数据的类型可以是任何数据类型. 一变量的命名    声明一个变量需注意: ①:变量可以以字母或者$._开头(后两 ...

  3. php模拟http请求的方法

    我在这里终结了三种方法 第一种方法:fsockopen $flag = 0; $post = ''; $errno = ''; $errstr = ''; //要post的数据 $argv = arr ...

  4. LCQCL

    Linux Command Quick Check List 记录一些我Linux使用中的问题的解决方案. # 挂起: 几乎只对RAM供电以保存工作状态的极低能耗状态. 任意键或电源键退出(主要看RP ...

  5. 使用 Git Hooks 实现自动项目部署

    最近在某服务器上面搭建 git 开发和部署环境,git 开发环境很简单,按照 ProGit 一书的相关知识就可以轻松搞定,实现了类似 Github 的使用 SSH + 私有 Clone 的方式. 关于 ...

  6. MySQL 专用备份软件参考

    1.MySQL Backup Tool   免费(需要安装 .NET 3.5)  https://sourceforge.net/projects/mysqlbutool/?source=typ_re ...

  7. css keyframes动画属性设置

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  8. websocket与socket.io

    什么是Websocket? Websocket是一个独立于http的实时通信协议,最初是在HTML5中被引用进来的,在HTML5规范中作为浏览器与服务器的核心通信技术被嵌入到浏览器中.WebSocke ...

  9. 我的CPG插件 (什么是CPG,就是跟号称全球唯一C++编写的魔镜是一样的格式的)

  10. 关于.NET知识体系结构图总结

    转载:关于.NET知识体系结构图总结-零度http://www.xcode.me/book/net-framework-maps 最近对.NET框架方面的知识进行了概要的总结,整理了一些知识体系结构图 ...