UVALive 3486

題意: 給一棵樹,每次每次詢問一個點是否是另一個點的祖先?
輸入父節點和它的兒子,數據量大,所以用棧結構防爆;

對於查詢是否是祖先,我們可以對於每一個節點打上兩個dfs標記,如果一個點是另一個點的祖先,那麼它的兩個標記一定在祖先的範圍之內。【tarjan的時間戳的概念】

注意每個樣例輸出之間要輸空行

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<stack>
#include<algorithm>
#define maxn 20022000
using namespace std;
typedef long long ll;
int n;
int child[maxn];
stack<int>st;
int clockk=0;
int vis[maxn];

struct a{
	int l,r;
}state[maxn];
struct b{
	int in,out;
}dfn[maxn];

void init(){
	clockk=0;
	while(!st.empty()) st.pop();
//	for(int i=0;i<maxn;i++)
}

void dfs(){
	for(int i=0;i<maxn;i++) vis[i]=0;
	st.push(0);
	while(!st.empty()){
		int x=st.top();
		if(!vis[x]){
			vis[x]=1;
			dfn[x].in=clockk++;
			if(x<n){
				int lchild=state[x].l,rchild=state[x].r;
				for(int i=lchild;i<=rchild;i++)	st.push(i);
			}
		}
		else{
			st.pop();
			dfn[x].out=clockk++;	
		}

	}
}


int main(){
	int T,x,m;
	scanf("%d",&T);
	int cas=0;
	while(T--){
		init();
		scanf("%d",&n);
		int y=1;
		for(int i=0;i<n;i++){
			scanf("%d",&x);
			state[i].l=y;
			state[i].r=y+x-1;
			y+=x;
		}
		dfs();
/*		for(int i=0;i<10;i++){
			printf("i=%d dfn[i].in=%d out=%d\n",i,dfn[i].in,dfn[i].out);
		}
*/		int u,v;
		scanf("%d",&m);
		if(cas++) printf("\n");
		printf("Case %d:\n",cas);
		for(int i=1;i<=m;i++){
			scanf("%d%d",&u,&v);
			bool f=false;
		//	printf("u=%d v=%d\n",u,v);
			if(dfn[u].in<dfn[v].in&&dfn[u].out>dfn[v].out)	printf("Yes\n");
			else printf("No\n");
		}
		
	}

	return 0;
} 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章