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;
}

  


 
原文地址:https://www.cnblogs.com/Fatedayt/p/2393488.html