您的位置:首页 > 产品设计 > UI/UE

HDU3686 Traffic Real Time Query System

2012-03-13 11:26 621 查看

HDU3686 Traffic Real Time Query System

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 881 Accepted Submission(s): 151


[align=left]Problem Description[/align]
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.

[align=left]Input[/align]
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

[align=left]Output[/align]
For each RTQ prints a line containing a single integer representing the number of crossings which the driver MUST pass.

[align=left]Sample Input[/align]

5 6
1 2
1 3
2 3
3 4
4 5
3 5
2
2 3
2 4
0 0

[align=left]Sample Output[/align]

0
1
**********************************************************
题目大意:一个城市有n个路口,m条无向公路。现在要求从第S条路到第T条路必须经过的点有几个。
解题思路:tarjan求点的双连通分量,然后缩点,然后LCA。
wa了良久,竟然因为:

1.题目要求的是从一条路到另一条路的必经点,不是从一个点到另一个点的必经点

2.这题虽说保证从roadS到roadT一定有路,但没说这个图是连通图,也就是缩点之后有多个树,不是只有一颗树

注意了上面两点就能AC。苦于因为从wa的代码改过来AC的,代码已经非常搓了。。。。

#include <map>
#include <stack>
#include <queue>
#include <math.h>
#include <vector>
#include <string>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#define N 200005
#define M 100005
#define E
#define inf 0x3f3f3f3f
#define eps 1e-8
#define LL long long
#define clr(a,b) memset(a,b,sizeof(a))
#define D(a) ((a)*(a))
using namespace std;

struct Node
{
int a,id;
Node(int t1,int t2):a(t1),id(t2){}
};
int x[M],y[M],eid[M],me[M];
int n,m,q,qu
[2],gp
,sum
;
int num
,ans
,vis
,fa
,gk
;
vector<int>gra
,tre
;
vector<Node>lca
;
int dfn
,low
,now,gid;
stack<int>sta;
stack<Node>ste;

int findfa(int s)
{
while(s!=fa[s])s=fa[s];
return s;
}

void tarjan(int s,int p)
{
dfn[s]=low[s]=++now;
int flag=0;
sta.push(s);
for(int i=0;i<gra[s].size();i++)
{
int e=gra[s][i];
if(me[e])continue;
me[e]=1;
int t=x[e];if(t==s)t=y[e];
ste.push(Node(e,t));
if(!dfn[t])
{
gk[t]=e;
tarjan(t,s);
low[s]=min(low[s],low[t]);
if(low[t]>=dfn[s])
{
if(flag==0)
{
num[++gid]=s;
flag=gp[s]=gid;
}
++gid;
tre[gp[s]].push_back(gid);
tre[gid].push_back(gp[s]);
while(!sta.empty())
{
int k=sta.top();
sta.pop();
if(gp[k])
{
int a=gp[k];
tre[a].push_back(gid);
tre[gid].push_back(a);
}
else gp[k]=gid;
if(k==t)break;
}
while(!ste.empty())
{
int ee=ste.top().a,hh=ste.top().id;
ste.pop();
eid[ee]=gid;
if(ee==gk[t])break;
}
}
}
low[s]=min(dfn[t],low[s]);
}
}

void LCA(int p,int s,int pre)
{
sum[p]=s;
if(num[p])s++;
for(int i=0;i<tre[p].size();i++)
{
int t=tre[p][i];
if(t!=pre)
{
LCA(t,s,p);
fa[findfa(t)]=p;
}
}
vis[p]=1;
for(int i=0;i<lca[p].size();i++)
{
int t=lca[p][i].a,id=lca[p][i].id;
if(vis[t])
{
int f=fa[findfa(t)];
ans[id]=sum[p]+sum[t]-2*sum[f];
if(num[f])ans[id]--;
}
}
}

void re(void)
{
for(int i=1;i<=n;i++)
gra[i].clear();
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
x[i]=a;y[i]=b;eid[i]=0;me[i]=0;
gra[a].push_back(i);
gra[b].push_back(i);
}
scanf("%d",&q);
for(int i=1;i<=q;i++)
scanf("%d%d",&qu[i][0],&qu[i][1]);
}

void run(void)
{
for(int i=1;i<=n;i++)
{
dfn[i]=num[i]=gp[i]=gk[i]=0;
tre[i].clear();
}
now=gid=0;
for(int i=1;i<=n;i++)
if(!dfn[i])
{
while(!sta.empty())sta.pop();
while(!ste.empty())ste.pop();
tarjan(i,0);
}
for(int i=1;i<=gid;i++)
{
lca[i].clear();
vis[i]=sum[i]=0;
fa[i]=i;
}
for(int i=1;i<=q;i++)
{
int a=eid[qu[i][0]],b=eid[qu[i][1]];
if(a==b)
{
ans[i]=0;
continue;
}
lca[a].push_back(Node(b,i));
lca[b].push_back(Node(a,i));
}
for(int i=1;i<=n;i++)
if(!vis[gp[i]])
LCA(gp[i],0,-1);
for(int i=1;i<=q;i++)
printf("%d\n",ans[i]);
}

int main()
{
while(scanf("%d%d",&n,&m),n+m)
{
re();
run();
}
return 0;
}


  


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: