UVALive-4839 HDU-3686 Traffic Real Time Query System 题解
题目大意:
有一张无向连通图,问从一条边走到另一条边必定要经过的点有几个。
思路:
先用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 题解的更多相关文章
- 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)(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 点双两通分量 + LCA。这题有重边!!!
http://acm.hdu.edu.cn/showproblem.php?pid=3686 我要把这题记录下来. 一直wa. 自己生成数据都是AC的.现在还是wa.留坑. 我感觉我现在倒下去床上就能 ...
- HDU 3686 Traffic Real Time Query System(点双连通)
题意 给定一张 \(n\) 个点 \(m\) 条边的无向图,\(q\) 次询问,每次询问两边之间的必经之点个数. 思路 求两点之间必经之边的个数用的是边双缩点,再求树上距离.而对比边双和点双之 ...
- 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 ...
- 【Targan+LCA】HDU 3686 Traffic Real Time Query
题目内容 洛谷链接 给出一个\(n\)个节点,\(m\)条边的无向图和两个节点\(s\)和\(t\),问这两个节点的路径中有几个点必须经过. 输入格式 第一行是\(n\)和\(m\). 接下来\(m\ ...
- 【HDOJ】3686 Traffic Real Time Query System
这题做了几个小时,基本思路肯定是求两点路径中的割点数目,思路是tarjan缩点,然后以割点和连通块作为新节点见图.转化为lca求解.结合点——双连通分量与LCA. /* 3686 */ #includ ...
- CH#24C 逃不掉的路 和 HDU3686 Traffic Real Time Query System
逃不掉的路 CH Round #24 - 三体杯 Round #1 题目描述 现代社会,路是必不可少的.任意两个城镇都有路相连,而且往往不止一条.但有些路连年被各种XXOO,走着很不爽.按理说条条大路 ...
- Traffic Real Time Query System 圆方树+LCA
题目描述 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, ...
随机推荐
- 原子类java.util.concurrent.atomic.*原理分析
原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...
- javascript中的变量
变量 var x = 0; 这是声明了一个变量的实例,我们可以把变量看做存储数据的容器.数据的类型可以是任何数据类型. 一变量的命名 声明一个变量需注意: ①:变量可以以字母或者$._开头(后两 ...
- php模拟http请求的方法
我在这里终结了三种方法 第一种方法:fsockopen $flag = 0; $post = ''; $errno = ''; $errstr = ''; //要post的数据 $argv = arr ...
- LCQCL
Linux Command Quick Check List 记录一些我Linux使用中的问题的解决方案. # 挂起: 几乎只对RAM供电以保存工作状态的极低能耗状态. 任意键或电源键退出(主要看RP ...
- 使用 Git Hooks 实现自动项目部署
最近在某服务器上面搭建 git 开发和部署环境,git 开发环境很简单,按照 ProGit 一书的相关知识就可以轻松搞定,实现了类似 Github 的使用 SSH + 私有 Clone 的方式. 关于 ...
- MySQL 专用备份软件参考
1.MySQL Backup Tool 免费(需要安装 .NET 3.5) https://sourceforge.net/projects/mysqlbutool/?source=typ_re ...
- css keyframes动画属性设置
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- websocket与socket.io
什么是Websocket? Websocket是一个独立于http的实时通信协议,最初是在HTML5中被引用进来的,在HTML5规范中作为浏览器与服务器的核心通信技术被嵌入到浏览器中.WebSocke ...
- 我的CPG插件 (什么是CPG,就是跟号称全球唯一C++编写的魔镜是一样的格式的)
- 关于.NET知识体系结构图总结
转载:关于.NET知识体系结构图总结-零度http://www.xcode.me/book/net-framework-maps 最近对.NET框架方面的知识进行了概要的总结,整理了一些知识体系结构图 ...