Greatest TCTime Limit: 12000/4000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission (s): 509 Accepted Submission (s): 148
Problem DescriptionTC (Tian Chao) is magical place, as you all know...
The railways and the rail-stations in TC are fragile and always meet with different kinds of problems. in order to reach the destination safely on time, you are asked to develop a system which has two types of main functions as below.
1: a B c d, reporting whether we can get from station A to station B without passing the railway that connects station C and station D.
2: a B c, reporting whether we can get from station A to station B without passing station C.
Please notice that the railways are UNDIRECTED.
InputFor each test case, the first line will contain two integers N (2 <= N <= 100000) and M (1 <= M <= 500000 ), namely the number of stations and railways in TC. then each of the next M lines will have two integers, describing the two stations that a certain railway is connecting. after this, there comes a line containing a single integer Q (Q <= 300000), which means the number of queries to make on the system. the next Q lines will be queries. each query begins with a integer, indicating the type of query, followed by 4 (the first type) or 3 (the second type) integers describing the details of the query as what mentioned above.
The stations are always labeled from 1 to N.
OutputFor each test case, print "yes" or "no" in separated lines for the queries.
Sample Input
13 151 22 33 52 44 62 61 41 77 87 97 108 118 129 1212 1351 5 13 1 21 6 2 1 41 13 6 7 82 13 6 72 13 6 8
Sample Output
yesyesyesnoyes
Question: Given a graph, there are two types of queries. The first one is from whether a-B passes through the c-d path and whether a-B passes through the c point.
According to tarjan, we can get a dfs sequence, record the timestamp of the first time that passes through this point, and the timestamp has left this point. Each point is accessed only once,
Record preprocessing multiply array.
For query 1, assume that c is under d to discuss the relationship between a, B and c. If a and B are all vertices in the subtree of c, or none of them exist, only need to discuss
A child tree in c is not in the same situation. If a is in the Child tree in c, if the low value of a is less than or equal to the dfn of c, it is obviously acceptable; otherwise, it cannot.
For query 2, if neither a nor B is in the subtree of c, it is obvious.
If they are all in the subtree of c, find pp and qq under a and B. If pp = qq, it is obviously not necessary to pass c. If pp, qq can find the point before c, then a, B can go through pp, qq
To reach the front of c, it is obvious that c can be bypassed.
The rest is a, and B has a sub-tree in c. If a, find the pp point under c. If pp exists, so whether pp can return to the front of c is acceptable.
Find the path that does not pass through c.
A disgusting question. After a day of hard work, I finally got an ac with the guidance of others, wa30times, and I am so confused.
Code:
/* ***********************************************Author :_rabbitCreated Time :2014/5/2 13:43:24File Name :12.cpp************************************************ */#pragma comment(linker, "/STACK:102400000,102400000")#include
#include
#include #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;#define INF 0x3f3f3f3f#define eps 1e-8#define pi acos(-1.0)typedef long long ll;const int maxn=101000;const int maxm=1001000;int head[maxn],tol;int low[maxn],dfn[maxn],indexx;int fa[maxn][20],dep[maxn],out[maxn];int vis[maxm];struct Edge{ int next,to;}edge[maxm];void addedge(int u,int v){ edge[tol].to=v; edge[tol].next=head[u]; head[u]=tol++;}void tarjan(int u,int deep){ low[u]=dfn[u]=++indexx; dep[u]=deep; for(int i=head[u];i!=-1;i=edge[i].next){ if(vis[i])continue; vis[i]=vis[i^1]=1; int v=edge[i].to; if(!dfn[v]){ tarjan(v,deep+1); fa[v][0]=u; low[u]=min(low[u],low[v]); } else low[u]=min(low[u],dfn[v]); } out[u]=indexx;}bool judge1(int a,int b,int c,int d){ if(dep[c]
=dfn[c]&&out[a]<=out[c])ina=1; if(dfn[b]>=dfn[c]&&out[b]<=out[c])inb=1; if((ina&&inb)||(!ina&&!inb))return 1; else{ if(low[c]<=dfn[d])return 1; return 0; }}int move(int x,int step){ if(step<0)return -1; for(int i=19;i>=0;i--) if((1<
=dfn[c]&&out[a]<=out[c])ina=1; if(dfn[b]>=dfn[c]&&out[b]<=out[c])inb=1; int flag=0; if(!ina&&!inb)flag=1; else if(ina&&!inb){ int pp=move(a,dep[a]-dep[c]-1); if(pp!=-1&&low[pp]