PTA 病毒溯源(树)

news/2024/7/7 15:11:19

题目

在这里插入图片描述

病毒容易发生变异。某种病毒可以通过突变产生若干变异的毒株,而这些变异的病毒又可能被诱发突变产生第二代变异,如此继续不断变化。

现给定一些病毒之间的变异关系,要求你找出其中最长的一条变异链。

在此假设给出的变异都是由突变引起的,不考虑复杂的基因重组变异问题 —— 即每一种病毒都是由唯一的一种病毒突变而来,并且不存在循环变异的情况。

输入格式:

输入在第一行中给出一个正整数 N(≤104 ),即病毒种类的总数。于是我们将所有病毒从 0 到 N−1 进行编号。

随后 N 行,每行按以下格式描述一种病毒的变异情况:

k 变异株1 …… 变异株k
其中 k 是该病毒产生的变异毒株的种类数,后面跟着每种变异株的编号。第 i 行对应编号为 i 的病毒(0≤i<N)。题目保证病毒源头有且仅有一个。

输出格式:

首先输出从源头开始最长变异链的长度。

在第二行中输出从源头开始最长的一条变异链,编号间以 1 个空格分隔,行首尾不得有多余空格。如果最长链不唯一,则输出最小序列。

注:我们称序列 { a 1 ,⋯,a n} 比序列 { b 1 ,⋯,b n } “小”,如果存在 1≤k≤n 满足 a i=b i对所有 i<k 成立,且 a k <b k。

  • 输入样例:
10
3 6 4 8
0
0
0
2 5 9
0
1 7
1 2
0
2 3 1
  • 输出样例:
4
0 4 9 1

题解

#include <iostream>
#include <vector>
#include <cstring>

using namespace std;

const int N = 10010;
const int M = N;
int h[N];
int e[N];
int ne[M];
int son[N];
int st[N];
int idx;
int n;
int max_val = -1;
int pos;

void add(int a, int b) {
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx++;
}

int dfs(int root) {
    int res = 0;
    son[root] = -1;
    for (int i = h[root]; i != -1; i = ne[i]) {
        int j = e[i];
        int t = dfs(j);
        if (t > res) {
            res = t;
            son[root] = j;
        }
        else if (res == t) {
            son[root] = min(son[root], j);
        }
    }
    return res + 1;
}

int main() {
    cin >> n;
    memset(h, -1, sizeof(h));

    for (int i = 0; i < n; i++) {
        int t;
        cin >> t;
        for (int j = 0; j < t; j++) {
            int tt;
            cin >> tt;
            add(i, tt);
            st[tt] = 1;
        }
    }

    for (int i = 0; i < n; i++) {
        if (st[i] == 0) {
            int t = dfs(i);
            if (t > max_val) {
                max_val = t;
                pos = i;
            }
        }
    }

    cout << max_val << endl;
    cout << pos;
    while (son[pos] != -1) {
        cout << " " << son[pos];
        pos = son[pos];
    }

    return 0;
}

思路

本题考察树的构建以及树的遍历,本题解使用静态链表对树进行存贮,使用递归的思想配合深搜算出最大深度,通过创建数组son来储存最长病毒链。本题考察的比较综合,要掌握好树的同时能够结合其他算法知识点,有一点笑笑的难度。


http://lihuaxi.xjx100.cn/news/1735731.html

相关文章

Mysql扩展语句和约束方式

一、扩展语句 使用工具Navicat创建表格 create TABLE if not exists carrot( id int(4) ZEROFILL primary key auto_increment, name varchar(10) not null, cardid int(18) not null unique key, hobby varchar (50) ); --------------------------------------------------…

【数据挖掘 | 数据预处理】缺失值处理 重复值处理 文本处理 确定不来看看?

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

GO语言,半自动打怪

仅供学习参考&#xff0c;切勿用于商业用途 package mainimport ("fmt""github.com/go-vgo/robotgo""math/rand""time" )const (taskNum 7 )type Task struct {Name stringSleepTime1 intSleepTime2 intFunc func() }fu…

K8S删除资源后一直处于Terminating状态无法删除解决方法

原因 使用kubectl delete 删除某命名空间是一直处于Terminating状态无法删除&#xff0c;首先排查了该命名空间下是否还存在deployment pod等资源发现没有后&#xff0c;等了很久还是无法删除后发现是因为该名称空间的“finalizers”字段有值导致 Finalizer&#xff08;终结器…

MySQL - 为什么需要 redo log?

为什么需要 redo log&#xff1f;&#xff1a; 数据恢复与一致性&#xff1a; Redo日志是数据库的事务日志&#xff0c;用于记录事务操作的细节&#xff0c;包括插入、更新和删除等。它确保了数据的持久性&#xff0c;即使在数据库发生崩溃或异常重启后&#xff0c;可以使用Re…

SpringMVC Day 06 : 转发视图

前言 在SpringMVC框架中&#xff0c;视图解析器可以将逻辑视图名称转换为实际的视图对象。除了直接渲染视图&#xff0c;你还可以通过SpringMVC提供的转发和重定向机制来跳转到另一个视图。在本篇博客中&#xff0c;我们将学习SpringMVC中的转发视图技术&#xff0c;以及如何使…

昂利康-002940 三季报分析(20231030)

昂利康-002940 基本面分析 基本情况 公司名称&#xff1a;浙江昂利康制药股份有限公司 A股简称&#xff1a;昂利康 成立日期&#xff1a;2001-12-30 上市日期&#xff1a;2018-10-23 所属行业&#xff1a;医药制造业 周期性&#xff1a;0 主营业务&#xff1a;化学原料药及制剂…

【机器学习】一、机器学习概述与模型的评估、选择

机器学习简介 由来 阿瑟.萨缪尔Arthur Samuel,1952年研制了一个具有自学习能力的西洋跳棋程序&#xff0c;1956年应约翰.麦卡锡John McCarthy&#xff08;人工智能之父&#xff09;之邀&#xff0c;在标志着人工智能学科诞生的达特茅斯会议上介绍这项工作。他发明了“机器学习…