HDU3686 Traffic Real Time Query System

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


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
**********************************************************
题目大意:一个城市有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[N][2],gp[N],sum[N];

int num[N],ans[N],vis[N],fa[N],gk[N];

vector<int>gra[N],tre[N];

vector<Node>lca[N];

int dfn[N],low[N],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;

}

  

 
   
 

你可能感兴趣的:(System)