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, ...
随机推荐
- Linux 双网卡绑定
Linux 双网卡绑定 Linux 双网卡绑定双网卡绑定的常用模式:mode1:active-backup 模式,即主备模式.mode0:round-broin 模式,即负载均衡模式(需要交换机配置聚 ...
- applicationContext.xml的基本配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- java中 IndexOf()、lastIndexOf()、substring()的用法
public int indexof(String str)返回字符串中出现str的第一个位置 public int indexof(String str,int fromIndex)返回字符串中从f ...
- linux shell输入重定向
经常用(隔很久)经常忘. 备忘下:http://blog.csdn.net/ithomer/article/details/9288353
- Eclipse导出插件工程
一.Feature Projecties工程设置 1. 新建一个Feature Projecties 2. 选择我们的插件工程,finish 3. 在目录下新建一个Category definitio ...
- 第3章 拍摄UFO——单一职责原则
就一个类而言,应该仅有一个引起它变化的原因
- strsep和strtok_r替代strtok
char *strtok(char *str, const char *delim) 会修改数据源.外部加锁才线程安全(strtok执行结束再解锁执行另一个strtok循环知道工作完成) 主要是以互斥 ...
- PCA 协方差矩阵特征向量的计算
人脸识别中矩阵的维数n>>样本个数m. 计算矩阵A的主成分,根据PCA的原理,就是计算A的协方差矩阵A'A的特征值和特征向量,但是A'A有可能比较大,所以根据A'A的大小,可以计算AA'或 ...
- web项目中各种路径的获取
以工程名为/DemoWeb为例: 访问的jsp为:http://localhost:8080/DemoWeb/test/index.jsp 1 JSP中获得当前应用的相对路径和绝对路径 (1)得到工程 ...
- 破解myEclipse
建立一个java项目,将reg.java放入,并且运行在控制台 输入账户 回车就会出现 序列号 菜单栏--->myeclipse-->substription information--- ...