列表

详情


NC205711. L2-4缘之空

描述

小悠和小穹是一对恋人,有天他们讨论起彼此的家庭,惊讶地发现他们很有可能是远房亲戚。
为了避免发生一些遗传学上比较糟糕的事情,他们决定求助于你,你能帮帮他们么?
家谱中有 n 个人,编号为 1 到 n, 他们的血缘关系形成了一棵有根树。
定义两个人之间的亲缘等级为家谱树上两个人的距离,直系血亲(即一个人是另一个人的祖先)和亲缘等级小于等于4的旁系血亲不能结婚。
小悠和小穹想知道,对于给定的两个人,他们能否结婚。

输入描述

第一行两个正整数 n, q, 表示家谱总人数和询问个数。
接下来 n-1 行,每行两个正整数 f, c, 表示 f 是 c 的父/母。(
接下来 q 行,每行两个正整数 u, v, 表示一个询问。(

输出描述

对于每个询问,第一行输出“YES”或者“NO”,表示两个人能否结婚。

第二行输出一个整数,表示两个人的亲缘等级。

示例1

输入:

7 3
1 2
1 3
2 4
2 5
3 6
6 7
1 3
4 6
5 7

输出:

NO
1
NO
4
YES
5

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 509ms, 内存消耗: 2012K, 提交时间: 2020-05-03 15:43:28

#include<bits/stdc++.h>
#define IO ios::sync_with_stdio(false), cin.tie(0)
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int n,m;
int f[100005];
int dep[100005];
int dfs(int x){
	if(dep[x]!=0||f[x]==0)return dep[x];
	else return dep[x]=dfs(f[x])+1;
}
void init(){
	cin>>n>>m;
	int fa,s;
	memset(f,0,sizeof(f));
	memset(dep,0,sizeof(dep));
	for(int i=1;i<n;i++){
		cin>>fa>>s;
		f[s]=fa;
	}
	for(int i=1;i<=n;i++){
		if(f[i]&&dep[i]==0){
			dfs(i);
		}
	}
//	cout<<"---"<<endl;
//	for(int i=1;i<=n;i++){
//		cout<<i<<" "<<dep[i]<<endl;
//	}
}
int lca(int ta,int tb){
	while(dep[ta]!=dep[tb]){
		if(dep[ta]>dep[tb]){
			ta=f[ta];
		}else{
			tb=f[tb];
		}
	}
	while(ta!=tb){
		ta=f[ta];
		tb=f[tb];
	}
	return ta;
}
int main()
{
	IO;
	init();
	for(int i=0;i<m;i++){
		int ta,tb;
		cin>>ta>>tb;
		int tmp=lca(ta,tb);
		//cout<<"tmp="<<tmp<<endl; 
		int dis=dep[ta]+dep[tb]-2*dep[tmp];
		if(dis<=4||ta==tmp||tb==tmp){
			cout<<"NO"<<endl<<dis<<endl;
		}else{
			cout<<"YES"<<endl<<dis<<endl;
		}
	}
 	return 0;
}
/*


*/ 




C++ 解法, 执行用时: 747ms, 内存消耗: 7656K, 提交时间: 2022-04-12 20:26:46

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,q,v[100005],d[100005],f[100005];
vector<ll>m[100005];
void build(ll now,ll de){
	v[now]=1;
	d[now]=de;
	ll l=m[now].size();
	for(int i=0;i<l;i++){
		ll to=m[now][i];
		if(!v[to]){
			build(to,de+1);
		}
	}
}
int main() {
	cin>>n>>q;
	ll x,y;
	for(int i=1;i<n;i++){
		cin>>x>>y;
		f[y]=x;
		m[x].push_back(y);
	}
	x=1;
	while(f[x])x=f[x];
	build(x,1);
	while(q--){
		cin>>x>>y;
		ll ans=0,flag=1;
		while(d[x]>d[y]){
			x=f[x];
			ans++;
		}
		while(d[y]>d[x]){
			y=f[y];
			ans++;
		}
		if(x==y){
			flag=0;
		}else{
			while(x!=y){
				x=f[x];
				y=f[y];
				ans+=2;
			}
			if(ans<=4)flag=0;
		}
		cout<<(flag==1?"YES":"NO")<<endl<<ans<<endl;
	}
	return 0;
}

上一题