Traffic Real Time Query System

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1929    Accepted Submission(s): 380
Problem Description
City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, the mayor plans to build a RTQS (Real Time Query System) to monitor all traffic situations. City C is made up of N crossings and M roads,
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.
 
Input
There are multiple test cases.
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
 
Output
For each RTQ prints a line containing a single integer representing the number of crossings which the driver MUST pass.
 
Sample Input
5 6
1 2
1 3
2 3
3 4
4 5
3 5
2
2 3
2 4
0 0
 
Sample Output
0
1
题意:给出一个无向连通图,然后给出S,T分别代表起始路和终止路的编号,问之间必须要经过的点有多少个?
分析:这样的点一定是割点,首先用tarjan算法找出割点(第一类点),然后求出点联通分量(边构成的块形成第二类点),缩点后形成一棵树,第一类点和第二类点是交叉相连的,所以用LCA找出最短路径后的距离/2就是结果;
程序:
#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)的更多相关文章

  1. poj 3694双联通缩点+LCA

    题意:给你一个无向连通图,每次加一条边后,问图中桥的数目. 思路:先将图进行双联通缩点,则缩点后图的边就是桥,然后dfs记录节点深度,给出(u,v)使其节点深度先降到同一等级,然后同时降等级直到汇合到 ...

  2. hdu 4612 双联通缩点+树形dp

    #pragma comment(linker,"/STACK:102400000,102400000")//总是爆栈加上这个就么么哒了 #include<stdio.h> ...

  3. 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 ...

  4. Codeforces 1000 组合数可行线段倒dp 边双联通缩点求树直径

    A /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std ...

  5. POJ3694 Network(边双连通分量+缩点+LCA)

    题目大概是给一张图,动态加边动态求割边数. 本想着求出边双连通分量后缩点,然后构成的树用树链剖分+线段树去维护路径上的边数和..好像好难写.. 看了别人的解法,这题有更简单的算法: 在任意两点添边,那 ...

  6. 图论-桥/割点/双连通分量/缩点/LCA

    基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成多个 ...

  7. lightoj 1291 无向图边双联通+缩点统计叶节点

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1291 #include<cstdio> #include<cstri ...

  8. BZOJ1123 [POI2008]BLO(割点判断 + 点双联通缩点size)

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; type ...

  9. hdu 2460 poj 3694 (双联通+LCA)

    在给出的两个点上加一条边,求剩下桥的数量,,不会LCA在线,就用了最普通的,先Tarjan双联通缩点,然后将缩完的图建成一棵树,树的所有边就是桥了,如果在任意两点间加一条边的话,那么从两点到最近公共祖 ...

随机推荐

  1. 随机数Math.random()公式

    1. 0-x之间的随机数: Math.round(Math.random()*x); 2. x至y之间的随机数 Math.round(Math.random()*(y-x)+x); 3. 1-x之间的 ...

  2. Openfire配置过程,以及与php交互注意事项。

    Ben Werdmuller 是一位 Web 策划师和开发人员,他专注于开放源码平台.他是开源社交网络框架 Elgg 的共同创始人和技术带头人.Ben 的博客 http://benwerd.com/. ...

  3. html测试代码框工具

    Code highlighting produced by Actipro CodeHighlighter (freeware) http://www.CodeHighlighter.com/ --& ...

  4. 详解JNDI的lookup资源引用 java:/comp/env

    ENC的概念:     The application component environment is referred to as the ENC, the enterprise naming c ...

  5. spring FactoryBean配置Bean

    概要: 实例代码具体解释: 文件夹结构 Car.java package com.coslay.beans.factorybean; public class Car { private String ...

  6. MVC中导航菜单,选中项的高亮问题。。

    先上图:             这个菜单是放在母板页的.比如当前选中的是异常业务监控.如果页面刷新了.就会变成第一张图..选择其他的选项也会,因为页面会刷新嘛.. 怎么处理这个问题了? 答案是记录当 ...

  7. 怎么快速了解自己的MySQL服务器?

    From: http://www.cnblogs.com/benshan/archive/2013/01/09/2853097.html 1.查看数据库服务器状态:status Linux 下的MyS ...

  8. 浮点纹理 opengl

    原文地址:http://wangqingyun84.blog.163.com/blog/static/790836172010323113604/ 因为 glsl部分 绑定fbo 看到要用浮点纹理,搜 ...

  9. jquery-file-upload附件上传

    引入样式和js文件 <link href="css/bootstrap.min.css" type="text/css" rel="styles ...

  10. Davlik虚拟机

    过几天得去面试,感觉原来做的东西都忘了. 有点累,无意看了下二师兄的小论文,想来原先自己也参与过一点点,所以记录下: Dalvik虚拟机中共有3种解释器,分别时SWITCH_INTERP,THREAD ...