边的双联通+缩点+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双联通缩点,然后将缩完的图建成一棵树,树的所有边就是桥了,如果在任意两点间加一条边的话,那么从两点到最近公共祖 ...
随机推荐
- PHP打印重复的东西
<?php echo str_repeat(" ", 8)?>//连续打印8个空格
- 选择列表中的列……无效,因为该列没有包含在聚合函数或 GROUP BY 子句中
今天用SQL Server尝试实现一个SQL语句的时候,报了如标题所示的错误,通过在百度里面搜索,并亲自动手实现,终于发现问题所在,现在把它记录下来. 语句如下: select [OrderID],[ ...
- e680. 使三元色图像变明变暗
This example demonstrates how to brighten or darken an RGB buffered image by scaling the red, green, ...
- C#代理多样性
一.代理 首先我们要弄清代理是个什么东西.别让一串翻译过来的概念把大家搞晕了头.有的文章把代理称委托.代表等,其实它们是一个东西,英文表述都是“Delegate”.由于没有一本权威的书来规范这个概念, ...
- motion的移植和使用
说明: motion主页:http://www.lavrsen.dk/foswiki/bin/view/Motion motion下载地址:http://sourceforge.net/project ...
- R语言barplot绘图函数
barplot 函数用于绘制柱状图,下面对其常用的参数进行一个详细的解释: 1)height : 高度,通过这个参数可以指定要画多少个柱子以及每个柱子的高度,其值有两种格式, 第一种 :向量 vect ...
- 网站性能测试PV到TPS的转换以及TPS的波动和淘宝性能测试要点
<淘宝性能测试白皮书V0.3> 性能测试的难点不在于测,在于测出的数据和实际的对照关系,以及测试出来的数据对性能的评估(到底是好,还是不好). 淘宝性能测试白皮书,解决了我的4个问题:1. ...
- SVN中Revert changes from this revision 跟Revert to this revision
譬如有个文件,有十个版本,假定版本号是1,2,3,4,5,6,7,8,9,10. Revert to this revision: 如果是在版本6这里点击“Revert to this revisio ...
- RAC:Oracle11gR2:启动gsd服务
/************/ 正在测试是否必须执行 gsdctl enable gsdctl start /************/ srvclt enable nodeapps -v srvctl ...
- swift--使用 is 和 as 操作符来实现类型检查和转换 / AnyObject与Any的区别
声明几个类: //动物类 class Animal{ } //陆地动物类 class terricole: Animal { } //海洋动物类 class SeaAnimals: Animal { ...