Traffic Real Time Query System

Traffic Real Time Query System

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 i th line (i starts from 1)contains two integers X i and Y i, representing that road i connects crossing X i and Y i (X i≠Y i).
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<X i,Y i<=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

一个城市有n个路口,m条无向公路。求从第S条路第T条路必须经过的点有几个。

Solution

挺明显的点双缩点,但最后找必经点的时候要用LCA,

首先必经过的一定是割点(问的是必经点嘛),因此可以先做点双连通然后缩点 缩完点后形成了树 ,这样的模式的u->v只要走一步,那就必经一个割点,路径u->v只需要求出他们的lca 则答案可以通过(dis[u]+dis[v]-dis[lca]*2)/2算出.

Code

#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;
typedef long long LL;
const int maxn=2e4+5,maxm=4e5+5;
int n,m,q,tot,idx,top;
int fu[maxm],fv[maxm];
int head[maxn],dfn[maxn],low[maxn],belong[maxm],st[maxm],tmp[maxn]; 
int vis[maxn],dis[maxn],lca[maxn][20];
struct Edge{int u,v,next;bool fg;}e[maxm];
pair<int,int> E[maxm];
void Init(){
	tot=0;idx=0;top=0;
	memset(head,-1,sizeof head);
	memset(dfn,0,sizeof dfn);
	memset(tmp,0,sizeof tmp);
	memset(vis,0,sizeof vis);
}
void Add(int x,int y){
	e[tot].u=x;
	e[tot].v=y;
	e[tot].fg=0;
	e[tot].next=head[x];
	head[x]=tot++;
}
void Tarjan(int u,int fa){
	dfn[u]=low[u]=++idx;
	int j,v;
	for(int i=head[u];~i;i=e[i].next){
		v=e[i].v;
		if(e[i].fg||dfn[v]>=dfn[u])continue;
		e[i].fg=e[i^1].fg=1;
		st[++top]=i;
		if(!dfn[v]){
			Tarjan(v,u);
			low[u]=min(low[u],low[v]);
			if(dfn[u]<=low[v]){
				n++;
				do{
					j=st[top--];
					if(tmp[e[j].v]!=n){
						E[m++]=make_pair(n,e[j].v);
						tmp[e[j].v]=n;
					}
					if(tmp[e[j^1].v]!=n){
						E[m++]=make_pair(n,e[j^1].v);
						tmp[e[j^1].v]=n;
					}
					belong[j>>1]=n;
				}while(j!=i);
			}
		}else low[u]=min(low[u],dfn[v]);
	}
}
void Mktb(int u,int from){
	vis[u]=1;
	dis[u]=dis[from]+1;
	lca[u][0]=from;
	for(int i=1;i<20;++i)lca[u][i]=lca[lca[u][i-1]][i-1];
	for(int i=head[u];~i;i=e[i].next){
		int v=e[i].v;
		if(v!=from&&!vis[v])Mktb(v,u);
	}
}
void Swap(int &a,int &b){int c=a;a=b;b=c;}
int LCA(int u,int v){
	if(dis[v]>dis[u])Swap(u,v);
	int tm=dis[u]-dis[v];
	for(int i=19;tm;i--)
		if(tm>=(1<<i))tm-=(1<<i),u=lca[u][i];
	if(u==v)return u;
	for(int i=19;i>=0;--i)
		if(lca[u][i]!=lca[v][i])u=lca[u][i],v=lca[v][i];
	return lca[u][0];
}
int main(){
	int u,v,f;
	while(scanf("%d%d",&n,&m)!=EOF){
		if(!n&&!m)return 0;
		Init();
		for(int i=1;i<=m;++i){
			scanf("%d%d",&u,&v);
			Add(u,v);Add(v,u);
			fu[i]=u;fv[i]=v;
		}
		m=0;
		for(int i=1;i<=n;++i)if(!dfn[i])Tarjan(i,i);
		tot=0;
		memset(head,-1,sizeof head);
		for(int i=0;i<m;++i){
			Add(E[i].first,E[i].second);
			Add(E[i].second,E[i].first);
		}
		for(int i=1;i<=n;++i)if(!vis[i])Mktb(i,0);
		scanf("%d",&q);
		int i,j;
		while(q--){
			scanf("%d%d",&i,&j);
			u=belong[i-1];
			v=belong[j-1];
			f=LCA(u,v);
			printf("%d\n",(dis[u]+dis[v]-dis[f]*2)>>1);
		}
	}
	return 0;
}
posted @ 2020-05-07 09:04  liuzhaoxu  阅读(316)  评论(0编辑  收藏  举报