天梯赛 愿天下有情人都是失散多年的兄妹(DFS)

一开始做的时候一直卡在17分,怎么看都觉得没有问题,最后看了别人博客才知道,竟然还会询问某人的父母和其他人的父母可否结婚(当然是选择原谅TA啦)。。。。像我这样纯洁的小孩子根本就考虑不到啊。。。
所以,在输入父母的序号时也需将性别标记上。

题目说要保证5代之间没有血缘关系,那么可以先找其中一人的5代并都进行标记,再找第二个人的5代,若第二个人的5代中有已经被标记的,那么说明他们不可以结婚。

此题的抽象模型类似于一颗二叉树。

#include <cstring>
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <set>
using namespace std;
struct peo{
    int id; char sex;
}peo[10011];
int fpre[10015], mpre[10015];
int vis1[10015];
bool flag = true;
void dfs(int f1,int m1,int cnt){
    if(cnt >= 5) return;
    if(!flag) return; // 存在血缘关系就退出
    if(f1 != -1){
        if(vis1[f1] == 1)
            flag = false;
        vis1[f1] = 1;
    }
    if(m1 != -1){
        if(vis1[m1] == 1)
            flag = false;
        vis1[m1] = 1;
    }

    if(f1 != -1) 
        dfs(fpre[f1], mpre[f1],cnt+1); // 父亲的父母
    if(m1 != -1)
        dfs(fpre[m1], mpre[m1],cnt+1); // 母亲的父母
}

int main(){
    int n; cin >> n;
    memset(fpre,-1,sizeof(fpre)); memset(mpre,-1,sizeof(mpre));
    for(int i = 0; i < n; ++i){
        int id; char sex; int f,m;
        cin >> id >> sex >> f >> m;
        peo[id].id = id; peo[id].sex = sex;
        fpre[id] = f; mpre[id] = m; // 父亲和母亲的序号
        peo[f].id = f; peo[f].sex = 'M'; // 写入父母的信息
        peo[m].id = m; peo[m].sex = 'F';
    }
    int ask;
    cin >> ask;
    while(ask--){
        int id1,id2; cin >> id1 >> id2;
        if(peo[id1].sex == peo[id2].sex){ // 本人也算作一代
            cout <<"Never Mind" << endl; continue;
        }
        flag = true;
        memset(vis1,0,sizeof(vis1)); 
        int f1 = fpre[id1], m1 = mpre[id1];
        int f2 = fpre[id2], m2 = mpre[id2];
        dfs(f1,m1,1); // 除去本人这一代,所以从1开始
        dfs(f2,m2,1);
        if(flag)
            cout <<"Yes" << endl;
        else
            cout <<"No" << endl;
    }
    return 0;
}
这个有趣的说法似乎是在引用网络流行语,但它并不是一个直接的编程题目。然而,如果你想要了解如何用C语言实现深度优先搜索(DFS),这是一个经典的图遍历算法,可以模拟查找两个节点之间的路径。以下是使用DFS的一个简单示例,假设我们有一个无向图,用邻接表表示: ```c #include <stdio.h> #include <stdlib.h> typedef struct Node { int value; struct Node* next; } Node; void DFS(Node** graph, int start, int goal) { Node* current = *graph[start]; while (current != NULL) { if (current->value == goal) { printf("找到了! %d -> %d\n", start, goal); return; } // 递归遍历当前节点的所有邻居 DFS(graph, current->value, goal); current = current->next; } printf("未找到路径从 %d 到 %d\n", start, goal); } // 添加边到邻接表 void addEdge(Node** graph, int src, int dst) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->value = dst; newNode->next = graph[src]; graph[src] = newNode; } int main() { int n; // 图的节点数 printf("请输入节点数:"); scanf("%d", &n); Node** graph = (Node**)malloc(n * sizeof(Node*)); for (int i = 0; i < n; ++i) { graph[i] = NULL; } // 根据输入添加边 for (int i = 0; i < n - 1; ++i) { int u, v; printf("请输入边 (%d, %d): ", i + 1, i + 2); scanf("%d %d", &u, &v); addEdge(&graph[u - 1], v - 1, i + 1); // 减一操作将用户输入转换为数组索引 } int start, end; printf("请输入开始节点和目标节点:"); scanf("%d %d", &start, &end); DFS(graph, start - 1, end - 1); // 再次减一处理用户输入 return 0; } ``` 这个程序首先创建一个邻接表来存储图,然后根据用户的输入添加边,并执行深度优先搜索来查找指定起点和终点之间的路径。请注意,这里的"失散多年兄妹"是一个比喻,实际上这里我们在找路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值