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, ...
随机推荐
- 转:C++项目中的extern "C" {}
引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: #ifdef __cplusplus extern "C" { #endif /*...*/ #ifdef __c ...
- BZOJ 3784: 树上的路径
Description 问一棵树上前 \(k\) 大路径的边权. Sol 边分治. 非常感谢数据没有菊花图. 为了写写边分治试试然后就开了这道题. 边分治非常好想,选一条重边,分成两部分,然后分别求最 ...
- Linux下查看磁盘与目录的容量——df、du
df:列出文件系统的整体磁盘使用量: du:评估文件系统的磁盘使用量(常用于评估目录所占容量) df参数: -a:列出所有的文件系统,包括系统特有的/proc等文件系统 -k:以KB的容量显示各文件系 ...
- Robot Framework用户手册 (版本:3.0)
版权信息:诺基亚网络和解决中心 本翻译尊重原协议,仅用于个人学习使用 1.开始: 1.1 介绍: Robot Framework是一个基于Python的,为终端测试和验收驱动开发(ATDD)的可扩展的 ...
- 《PHP中的Math函数》笔记
① abs() 绝对值; ② ceil() 向上取整; ③ floor() 向下取整; ④ fmod() 返回除法的浮点数余数; ⑤ getrandmax() 显示随机数最大的可能值; ⑥ is_fi ...
- linux查看安装文件
rpm -qa jdk 查看名字包含"jdk"的已安装的文件 which java 查看java命令的所在目录 rpm -qf `which java` 查看java命令所对应的安 ...
- DevExpress 在使用Ribbon皮肤时标题栏不变化的原因
将 form的 AllowFormGlass 属性 该为False 就可以标题栏皮肤化了.
- input函数出现的问题(Python)
参考书<A Learner's Guide to Programming Using the Python Language>,写下如下的程序: # coding=utf-8 # 以上是为 ...
- int ,long , long long类型的范围
int ,long , long long类型的范围 unsigned - - unsigned - - unsigned __int64的最大值: __int64的最小值:- unsigned __ ...
- swift错误 Expressions are not allowed at the top level
``` ... earlier we said top-level code isn't allowed in most of your app's source files. The excepti ...