URAL 1329. Galactic History

7 篇文章 2 订阅


题意:给定一个树,有L<=40000个询问,问两个节点的从属关系。

只记录每个点的父节点,直接搜索,超时。

于是,先记录下所有的问题,然后一次DFS求出所有的答案。

对于每组询问,先碰到某个节点,就令TimeOn>0 然后搜索完这个点的子节点后,TimeOn=0;

如果在TimeOn>0的时间内搜不到另一个节点,证明两点没有从属关系,回答0;

否则存在从属关系。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define FOR(i,n) for(long long (i)=1;(i)<=(n);(i)++)
#define For(i,n) for(long long (i)=0;(i)<(n);(i)++)
using namespace std;
int N,L;
struct ArcNode{
	int to;
	ArcNode*next;
};
struct Question{
	int a,b;
	bool Ta,Tb;//记录是否包含另一个.
	int TimeOn;//1表示先碰到 a , 2表示先碰到  b  0表示未碰到或时间已过 
}Q[40001];
struct Node{
	ArcNode*List;
	ArcNode*QList;
}node[40001];
void Arc(int from,int to){
	ArcNode *temp=new ArcNode;
	temp->to=to;
	temp->next=node[from].List;
	node[from].List=temp;
}
void Arc2(int from,int to){
	ArcNode *temp=new ArcNode;
	temp->to=to;
	temp->next=node[from].QList;
	node[from].QList=temp;
}
void dfs(int rt){
	ArcNode*temp=node[rt].QList;
	while(temp){
		if(Q[temp->to].TimeOn){
			if(Q[temp->to].TimeOn==1&&rt==Q[temp->to].b) Q[temp->to].Ta=1;
			if(Q[temp->to].TimeOn==2&&rt==Q[temp->to].a) Q[temp->to].Tb=1;  
		}
		else{
			if(rt==Q[temp->to].a) Q[temp->to].TimeOn=1;
			if(rt==Q[temp->to].b) Q[temp->to].TimeOn=2;
		}
		temp=temp->next;
	}
	temp=node[rt].List;
	while(temp){
		dfs(temp->to);
		temp=temp->next;
	}
	temp=node[rt].QList;
	while(temp){
		Q[temp->to].TimeOn=0;
		temp=temp->next;
	}
}
int main(void)
{
	while(cin>>N){
		int a,b;
		FOR(i,40000) node[i].List=NULL,node[i].QList=NULL;
		int rt=-1;
		//建树 
		For(i,N){
			scanf("%d%d",&a,&b);
			if(!~b) rt=a;
			else Arc(b,a); 	
		}
		cin>>L;
		//记录问题 
		For(i,L){
			scanf("%d%d",&Q[i].a,&Q[i].b);
			Arc2(Q[i].a,i);
			Arc2(Q[i].b,i);
			Q[i].TimeOn=0;
		}
		//求解 
		dfs(rt);
		//输出 
		For(i,L){
			printf("%d\n",(int)Q[i].Ta+(int)Q[i].Tb*2);
		}
	}
return 0;
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值