边的双联通+缩点+LCA(HDU3686)
Traffic Real Time Query System
and each road connects two crossings. All roads are bidirectional. One of the important tasks of RTQS is to answer some queries about route-choice problem. Specifically, the task is to find the crossings which a driver MUST pass when he is driving from one
given road to another given road.
For each test case:
The first line contains two integers N and M, representing the number of the crossings and roads.
The next M lines describe the roads. In those M lines, the ith line (i starts from 1)contains two integers Xi and Yi, representing that roadi connects crossing Xi and Yi (Xi≠Yi).
The following line contains a single integer Q, representing the number of RTQs.
Then Q lines follows, each describing a RTQ by two integers S and T(S≠T) meaning that a driver is now driving on the roads and he wants to reach roadt . It will be always at least one way from roads to roadt.
The input ends with a line of “0 0”.
Please note that: 0<N<=10000, 0<M<=100000, 0<Q<=10000, 0<Xi,Yi<=N, 0<S,T<=M
#include"string.h"
#include"stdio.h"
#include"iostream"
#include"queue"
#include"stack"
#define M 10009
#define N 100009
#include"stdlib.h"
#include"math.h"
#define inf 99999999
using namespace std;
struct node//构建原图
{
int u,v,next,vis;
}edge[N*];
stack<int>q;
int t,head[M],dfn[M],low[M],cut[M],use[N*],index,num,belong[N*];
struct Tree//缩点后的图
{
int v;
Tree(){}
Tree(int vv):v(vv){}
};
vector<Tree>Edge[M+N];
void init()
{
t=;
memset(head,-,sizeof(head));
memset(edge,,sizeof(edge));
}
void add(int u,int v)//原图建边
{
edge[t].u=u;
edge[t].v=v;
edge[t].next=head[u];
head[u]=t++;
}
void tarjan(int u,int fa)
{
dfn[u]=low[u]=++index;
for(int i=head[u];i!=-;i=edge[i].next)
{
int v=edge[i].v;
if(edge[i].vis)continue;
edge[i].vis=edge[i^].vis=;
q.push(i);
if(!dfn[v])
{
tarjan(v,u);
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u])//求割点
{
num++;
cut[u]++;
int j;//求边联通块
do
{
j=q.top();
q.pop();
belong[j]=belong[j^]=num;//形成边连通块
}while(j!=i);
}
}
else
low[u]=min(low[u],dfn[v]);
}
if(fa<)
cut[u]--;
}
void solve(int n)
{
index=num=;
memset(dfn,,sizeof(dfn));
memset(cut,,sizeof(cut));
for(int i=;i<=n;i++)
if(!dfn[i])
tarjan(i,-);
}
struct LCA
{
int u,v,w,next;
}lca[N*];
int t1,head1[N*],f[N*],dis[N*];
void Init()
{
t1=;
memset(head1,-,sizeof(head1));
}
void Addlca(int u,int v)
{
lca[t1].u=u;
lca[t1].v=v;
lca[t1].next=head1[u];
head1[u]=t1++;
}
int finde(int x)
{
if(x!=f[x])
f[x]=finde(f[x]);
return f[x];
}
void make(int a,int b)
{
f[finde(a)]=finde(b);
}
void dfs(int u)//离线LCA算法
{
use[u]=;
for(int i=;i<(int)Edge[u].size();i++)
{
int v=Edge[u][i].v;
if(!use[v])
{
dis[v]=dis[u]+;
dfs(v);
f[v]=u;
make(u,v);
}
}
for(int i=head1[u];i!=-;i=lca[i].next)
{
int v=lca[i].v;
if(use[v])
lca[i].w=lca[i^].w=f[finde(v)];
}
}
void slove()
{
dis[]=;
for(int i=;i<=num;i++)
f[i]=i;
memset(use,,sizeof(use));
for(int i=;i<=num;i++)
if(!use[i])
dfs(i);
for(int i=;i<t1;i+=)
{
int u=lca[i].u;
int v=lca[i].v;
int mid=lca[i].w;
printf("%d\n",(dis[u]+dis[v]-*dis[mid])/);
}
}
int main()
{
int n,m,i,u,v;
while(scanf("%d%d",&n,&m),m||n)
{
init();
for(i=;i<m;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
solve(n);//求割点和边联通块
memset(use,,sizeof(use));
for(u=;u<=n;u++)
{
if(cut[u])
{
++num;//在边的联通块的序号之上继续给割点编号
for(i=head[u];i!=-;i=edge[i].next)
{
if(!use[belong[i]])//某个割点和相邻某条边建边后即与边联通块连接,应该去重
{
Edge[num].push_back(belong[i]);
Edge[belong[i]].push_back(num);
use[belong[i]]=;
}
}
for(i=head[u];i!=-;i=edge[i].next)
use[belong[i]]=;
}
}
int Q;
scanf("%d",&Q);
Init();
while(Q--)
{
scanf("%d%d",&u,&v);//输入的是原始边的排列序号
Addlca(belong[u*-],belong[v*-]);//把边映射到边联通块中
Addlca(belong[v*-],belong[u*-]);
}
slove();
for(i=;i<=num;i++)
Edge[i].clear();
}
}
边的双联通+缩点+LCA(HDU3686)的更多相关文章
- poj 3694双联通缩点+LCA
题意:给你一个无向连通图,每次加一条边后,问图中桥的数目. 思路:先将图进行双联通缩点,则缩点后图的边就是桥,然后dfs记录节点深度,给出(u,v)使其节点深度先降到同一等级,然后同时降等级直到汇合到 ...
- hdu 4612 双联通缩点+树形dp
#pragma comment(linker,"/STACK:102400000,102400000")//总是爆栈加上这个就么么哒了 #include<stdio.h> ...
- 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 ...
- Codeforces 1000 组合数可行线段倒dp 边双联通缩点求树直径
A /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std ...
- POJ3694 Network(边双连通分量+缩点+LCA)
题目大概是给一张图,动态加边动态求割边数. 本想着求出边双连通分量后缩点,然后构成的树用树链剖分+线段树去维护路径上的边数和..好像好难写.. 看了别人的解法,这题有更简单的算法: 在任意两点添边,那 ...
- 图论-桥/割点/双连通分量/缩点/LCA
基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...
- lightoj 1291 无向图边双联通+缩点统计叶节点
题目链接:http://lightoj.com/volume_showproblem.php?problem=1291 #include<cstdio> #include<cstri ...
- BZOJ1123 [POI2008]BLO(割点判断 + 点双联通缩点size)
#include <iostream> #include <cstring> #include <cstdio> using namespace std; type ...
- hdu 2460 poj 3694 (双联通+LCA)
在给出的两个点上加一条边,求剩下桥的数量,,不会LCA在线,就用了最普通的,先Tarjan双联通缩点,然后将缩完的图建成一棵树,树的所有边就是桥了,如果在任意两点间加一条边的话,那么从两点到最近公共祖 ...
随机推荐
- js学习笔记29----拖拽
原理:先计算鼠标与拖拽目标的左侧距离 跟 上面距离,再计算拖动后的位置. 示例代码: <!DOCTYPE html> <html lang="en"> &l ...
- 怎么让一个div 悬浮在另一个div上
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- jquery动态分页
最近一直研究jquery的分页效果,刚刚弄好了一个,拿出来与大家分享.分页效果与时光网的差不多. 网址:http://www.mtime.com/movie/news/all/ 先在aspx页面放置一 ...
- selenium测试(Java)--关闭窗口(二十)
quit方法:退出相关的驱动程序和关闭所有窗口 close方法:关闭当前窗口 package com.test.closewindow; import java.util.Iterator; impo ...
- JS中setInterval、setTimeout不能传递带参数的函数的解决方法
setInterval 和 setTimeout 这两个函数比较好用,但会遇到比如说我隔个几秒后要执行的函数是带参数的,这种情况怎么办?可以用匿名函数包装处理 //不带参数的函数 function t ...
- linux -- ubuntu dash bash
终端:即所谓的命令行界面,又称命令终端,用户输入shell命令用的窗口,跟Windows里的DOS界面差不多. shell:意为“壳”,是操作系统与用户交互用的接口,在命令终端里可以使用shell.s ...
- oracle jar
关于oracle 11g jdbc驱动 的jar包 (2012-11-21 11:17:41)转载▼ 标签: 杂谈 分类:java学习 oracle11的jdbc\lib下没有classer12.ja ...
- mysql的优化:官网地址
http://dev.mysql.com/doc/refman/5.1/zh/optimization.html#index-merge-optimization
- KEGG orthology (KO) 数据库简介
KEGG, 简称京都基因组百科全书,包含了许多的数据库,对于研究基因功能来说,KEGG orthology 数据库是最基本的一个数据库: KEGG Orthology 简称KO, 对于每个功能已知的基 ...
- MathTyp使用过程的几个问题
最近毕业季,人们又开始了一波论文恐惧症了.每天都在不断地改来改去,格式还是不符合要求,头疼得要死.不仅如此,还发现公式是越改越乱,牵一发而全身,其它地方动一点,整个版面全都乱了,人都要抓狂了.知道你的 ...