题目解析
给定n个病毒
求出 从源头开始最远的变异长度 及 字典序最小的变异链
解题思路
直接上图好理解这个

我们找到了根节点之后直接看里面 距离根节点的最长长度是多少 以及 字典序最小的序列
很显然 长度是4 变异链是 0 4 9 1
然后直接搜就完事了
我们先找出根节点是那个
然后从根节点开始往下搜
每次去记录要到最远距离的节点 也就是 变异链往下的最小节点
注: java 不知道为啥第5个测试数据一直出现答案错误
代码
java
import java.io.*;
import java.util.*;
public class Main
{
static int N = (int) 1e4 + 10;
static ArrayList<Integer> ar[] = new ArrayList[N];
static int son[] = new int[N]; // 表示最后答案中 当前节点的子节点
static boolean use[] = new boolean[N]; // 每个节点是否为非根节点
static int dfs(int u)
{
int max = 0;
son[u] = -1;
for (int i = 0; i < ar[u].size(); i++)
{
int j = ar[u].get(i);
// 根节点到当前节点的距离
int d = dfs(j);
// 如果 根节点到该节点的距离 大于 当前找到的最大
if (d > max)
{
son[u] = j; // 父亲节点 的下一个节点 为 当前节点
max = d; // 更新当前找到的最大值
}
// 因为最后的输出需要字典序最小 所以需要最小的
else if (d == max)
son[u] = Math.min(son[u], j);
}
return max + 1;
}
public static void main(String[] args) throws IOException
{
int n = ini();
for (int i = 0; i < n; i++)
{
ar[i] = new ArrayList<Integer>();
int k = ini();
while (k-- > 0)
{
int x = ini();
ar[i].add(x);
use[x] = true; // 标记这个点为非根节点
}
}
// 找根节点
int root = 0;
while (use[root])
root++;
// 初始化
Arrays.fill(son, -1);
// 输出距离根节点最远的距离
out.println(dfs(root));
out.print(root);
root = son[root];
while (root != -1)
{
out.print(" " + root);
root = son[root];
}
out.flush();
out.close();
}
static StreamTokenizer sc = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter out = new PrintWriter(System.out);
static int ini() throws IOException
{
sc.nextToken();
return (int) sc.nval;
}
}
c++
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int N = 1e4 + 10;
vector<int> ar[N];
int son[N];
bool use[N];
int dfs(int u)
{
int max = 0;
son[u] = -1;
for(int i = 0; i < ar[u].size(); i ++)
{
int j = ar[u][i];
int d = dfs(j);
if(d > max)
{
son[u] = j;
max = d;
}
else if(d == max)
son[u] = min(son[u], j);
}
return max + 1;
}
int main()
{
int n; cin >> n;
for(int i = 0; i < n; i ++)
{
int k; cin >> k;
while(k -- > 0)
{
int x; cin >> x;
ar[i].push_back(x);
use[x] = true;
}
}
int root = 0;
while(use[root]) root++;
for(int i = 0; i < n; i ++) son[i] = -1;
cout << dfs(root) << endl;
cout << root;
root = son[root];
while(root != -1)
{
cout << " " << root;
root = son[root];
}
return 0;
}