边的双联通+缩点+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双联通缩点,然后将缩完的图建成一棵树,树的所有边就是桥了,如果在任意两点间加一条边的话,那么从两点到最近公共祖 ...
随机推荐
- css鼠标移动到文字上怎样变化背景颜色
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- C#程序运行流程
我们写好的C#代码操作系统是如何能识别呢,我们都知道操作系统只能认识二进制 机器代码,下面用图来表示 因为C#是安全的托管代码 同时CLR会在内存中创建应用程序域 托管代码:被CLR管理的代码 非托管 ...
- 将DataFrame数据如何写入到Hive表中
1.将DataFrame数据如何写入到Hive表中?2.通过那个API实现创建spark临时表?3.如何将DataFrame数据写入hive指定数据表的分区中? 从spark1.2 到spark1.3 ...
- php 三级连动及 php+ajax的调试方法
js获得select的value值 把这个值以ajax的方法传给外页php处理 php得到这个value值,把它作为查询条件进行处理 ajax很神奇,会把这个结果显现出来 总之,ajax负责传值和显示 ...
- 颜色ARGB的混合
Alpha 透明度混合算法,网上收集整理,分成以下三种: 一. R1,G1,B1,Alpha1 为前景颜色值[混合颜色 上图层],R2,G2,B2,Alpha2 为背景颜色值[混合颜色 下图层],则 ...
- 【转】 PreTranslateMessage作用和使用方法
PreTranslateMessage作用和使用方法 PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,绝大多数本窗口的消息都要通过这里,比较常用, ...
- 无法从“重载函数类型”为“const std::_Tree<_Traits> &”推导 <未知> 参数
场景: 原因: 用到string类型,但是没有包含头文件. 解决方法: #include<string>
- e662. 取的图像的色彩模型
// This method returns the color model of an image public static ColorModel getColorModel(Image imag ...
- 用 #include “filename.h” 格式来引用非标准库的头文件
用 #include “filename.h” 格式来引用非标准库的头文件(编译器将 从用户的工作目录开始搜索) #include <iostream> /* run this progr ...
- 【Java面试题】35 List, Set, Map是否继承自Collection接口?
Collection是最基本的集合接口,声明了适用于JAVA集合(只包括Set和List)的通用方法. Set 和List 都继承了Conllection:Set具有与Collection完全一样的接 ...