愿天下有情人都是失散多年的兄妹思考

本文介绍了一种基于深度优先搜索(DFS)和广度优先搜索(BFS)的算法来判断两个人是否为五代以内的亲属关系。该算法首先记录了家族成员的基本信息,并通过DFS和BFS遍历家族树,确保遍历不超过五代,同时避免重复访问同一节点。此外,还提供了一种使用队列结构进行DFS的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个题可以用dfs,bfs等等方法去看五代的情况,用dfs挺复杂的

#include<bits/stdc++.h>
using namespace std;
int cnt=0;
set<int> c;
int vis[100100],exist[100100],yvis[100100];
struct people{
  int sex;
  int id;
  int fa;
  int ma;
}pe[100100];
void dfs(int x,int layer)
{
  if(!vis[x])
  {
    vis[x]=1;
    if(layer<=5)
    {
      
    c.insert(x);
    if(exist[x])
    {
      if(pe[x].fa!=-1)
      {
        dfs(pe[x].fa,layer+1);
      }
      if(pe[x].ma!=-1)
      {
        dfs(pe[x].ma,layer+1);
      }
    }
    }
    
  }
}
bool ydfs(int x,int layer)
{
  if(!yvis[x])
  {
    yvis[x]=1;
    if(layer<=5)
    {
      cnt=c.size();
      c.insert(x);
      if(c.size()==cnt)
      {
        return false;
      }
      if(exist[x])
      {
        if(pe[x].fa!=-1)
        {
          if(!ydfs(pe[x].fa,layer+1))
          {
          return false;  
          }
        }
        if(pe[x].ma!=-1)
      {
        if(!ydfs(pe[x].ma,layer+1))
        {
          return false;
        }
      }
      }
    }
    return true;
  }
  
}
int main(){
  int n,i,j=0,x,y,flag,t,a[100010],b[100010];
  cin>>n;
  
  char r;
  memset(exist,0,sizeof(exist));
  for(i=0;i<n;i++)
  {
    cin>>t;
    exist[t]=1;
    pe[t].id=t;
    cin>>r;
    if(r=='F')
    {
      pe[t].sex=0;
    }
    else{
      pe[t].sex=1;
    }
    cin>>pe[t].fa;
    cin>>pe[t].ma;
   }
   cin>>t;
    for(i=0;i<t;i++)
    {
      memset(vis,0,sizeof(vis));
      memset(yvis,0,sizeof(yvis));
      c.clear();
      cin>>x;
      cin>>y;
      if(pe[x].sex==pe[y].sex)
      {
        cout<<"Never Mind"<<endl;
        continue;
      }
      dfs(y,1);
      cnt=c.size();
      
      
      if(ydfs(x,1))
      {
        cout<<"Yes"<<endl;
      }
      else{
        cout<<"No"<<endl;
      }
      
    }
  return 0;
}

上面是dfs的实现,下面通过bfs实现

#include<bits/stdc++.h>
using namespace std;
int cnt=0;
set<int> c;
int vis[100100],exist[100100],yvis[100100],level[100010];
struct people{
	int sex;
	int id;
	int fa;
	int ma;
}pe[100100];
int main(){
	int n,i,j=0,x,y,flag,cnt,t,a,b;
	cin>>n;
	
	char r;
	memset(exist,0,sizeof(exist));
	for(i=0;i<n;i++)
	{
		cin>>t;
		exist[t]=1;
		pe[t].id=t;
		cin>>r;
		if(r=='F')
		{
			pe[t].sex=0;
		}
		else{
			pe[t].sex=1;
		}
		cin>>pe[t].fa;
		if(pe[t].fa!=-1)
		{
				pe[pe[t].fa].sex=1;
		}
	
		cin>>pe[t].ma;
		if(pe[t].ma!=-1)
		{
				pe[pe[t].ma].sex=0;
		}
	
	 }
	 cin>>t;
	 for(i=0;i<t;i++)
	 {
	 	flag=0;
	 	fill(level,level+100010,0);
	 	cin>>x;
	 	cin>>y;
	 	if(pe[x].sex==pe[y].sex)
	 	{
	 		cout<<"Never Mind"<<endl;
	 		continue;
		 }
	 	c.clear();
	 	level[x]=1;
	 	level[y]=1;
	 	queue<int> qu;
		qu.push(x);
		qu.push(y);
		while(!qu.empty())
		{
			a=qu.front();
			qu.pop();
		
			if(level[a]>5)
			{
				break;
			}
		
			else{
				cnt=c.size();
				c.insert(a);
				if(c.size()==cnt)
				{
					cout<<"No"<<endl;
					flag=1;
					break;
				}
				else{
					if(exist[a])
					{
					
						if(pe[a].fa!=-1)
						{
							level[pe[a].fa]=level[a]+1;
							qu.push(pe[a].fa);
						}
						if(pe[a].ma!=-1)
						{
							level[pe[a].ma]=level[a]+1;
							qu.push(pe[a].ma);
						}
							
						
					}
				}
			}
		}
		if(flag==0)
		{
			cout<<"Yes"<<endl;
		}
	 }
	
	return 0;
}

以下是dfs另一种查找思路的实现

#include<bits/stdc++.h>
using namespace std;
int cnt=0;
set<int> c;
int vis[100100],exist[100100],top,ans;
vector<int> queu;
struct people{
	int sex;
	int id;
	int fa;
	int ma;
}pe[100100];
void dfs(int x,int layer,int mo)
{
	if(layer>5)return;
	int i,j;
	if(mo==0)
	{
		queu.push_back(x);
		if(exist[x])
		{
			if(pe[x].fa!=-1)
			{
				dfs(pe[x].fa,layer+1,0);
			}
			if(pe[x].ma!=-1)
			{
				dfs(pe[x].ma,layer+1,0);
			}
		}
	}
	else{
		
		if(find(queu.begin(),queu.end(),x)!=queu.end())
		{
		
			ans=1;
			return;	
			
			
		}
		else{
			if(exist[x])
		{
			if(pe[x].fa!=-1)
			{
				dfs(pe[x].fa,layer+1,1);
			}
			if(pe[x].ma!=-1)
			{
				dfs(pe[x].ma,layer+1,1);
			}
		}
		}
	}
}
int main(){
	int n,i,j=0,x,y,flag,cnt,t,a,b;
	cin>>n;
	
	char r;
	memset(exist,0,sizeof(exist));
	for(i=0;i<n;i++)
	{
		cin>>t;
		exist[t]=1;
		pe[t].id=t;
		cin>>r;
		if(r=='F')
		{
			pe[t].sex=0;
		}
		else{
			pe[t].sex=1;
		}
		cin>>pe[t].fa;
		if(pe[t].fa!=-1)
		{
				pe[pe[t].fa].sex=1;
		}
	
		cin>>pe[t].ma;
		if(pe[t].ma!=-1)
		{
				pe[pe[t].ma].sex=0;
		}
	
	 }
	 cin>>t;
	 for(i=0;i<t;i++)
	 {
	 	
	 	
	 	cin>>x;
	 	cin>>y;
	 	
	 	if(pe[x].sex==pe[y].sex)
	 	{
	 		cout<<"Never Mind"<<endl;
	 		continue;
		 }
		 top=0;
		 ans=0;
		 queu.clear();
	 	dfs(x,1,0);
	 	dfs(y,1,1);
	 if(ans==1)
	 {
	 	cout<<"No"<<endl;
	 }
	 else{
	 		cout<<"Yes"<<endl;
	 }
	 	
		
	 }
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值