思路:一看题目给的数据,就想起来并查集,将并查集的find()函数简单修改即可达到要求。(但是我使用Java写的无法通过,显示答案错误,同样的方法在C++中却得以全部通过,让我很是疑惑)
核心部分
static int[] map; // 输入数据
static int[] record; // 记录辈分
static int find(int val) {
if (record[val] != 0) {// 辈分已经知道,直接退出
return record[val];
}
if (map[val] == -1) { // 是老祖宗
return record[val] = 1;
}
// 不是老祖宗,继续往下找,并确定自己的辈分
return record[val] = find(map[val]) + 1;
}
Java代码(没有通过,答案错误)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
Reader.init(System.in);
int N = Reader.nextInt();
map = new int[100005];
record = new int[100005];
for (int i = 1; i <= N; i++) {
map[i] = Reader.nextInt();
}
for (int i = 1; i <= N; i++) {
find(i);
if (max < record[i])
max = record[i];
}
System.out.println(max);
boolean first = true;
for (int i = 1; i <= N; i++) {
if (record[i] == max) {
if(first) {
first = false;
System.out.print(i);
}else {
System.out.print(" " + i);
}
}
}
}
static int max = 0; // 确定最大辈分
static int[] map; // 输入数据
static int[] record; // 记录辈分
static int find(int val) {
if (record[val] != 0) {// 辈分已经知道,直接退出
return record[val];
}
if (map[val] == -1) { // 是老祖宗
return record[val] = 1;
}
// 不是老祖宗,继续往下找,并确定自己的辈分
return record[val] = find(map[val]) + 1;
}
}
// Class for buffered reading int and double values *//*
class Reader {
static BufferedReader reader;
static StringTokenizer tokenizer;
// ** call this method to initialize reader for InputStream *//*
static void init(InputStream input) {
reader = new BufferedReader(new InputStreamReader(input));
tokenizer = new StringTokenizer("");
}
static void init(File file) {
try {
reader = new BufferedReader(new FileReader(file));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tokenizer = new StringTokenizer("");
}
// ** get next word *//*
static String next() throws IOException {
while (!tokenizer.hasMoreTokens()) {
// TODO add check for eof if necessary
tokenizer = new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
static String nextLine() throws IOException {
return reader.readLine();
}
static int nextInt() throws IOException {
return Integer.parseInt(next());
}
static char nextChar() throws IOException {
return next().toCharArray()[0];
}
static float nextFloat() throws IOException {
return Float.parseFloat(next());
}
static Double nextDouble() throws IOException {
return Double.parseDouble(next());
}
}
C++代码(全部通过)
#include<iostream>
using namespace std;
int map[100005];
int record[100005];
int find(int i){
if(record[i]!=0){
return record[i];
}
if(map[i]==-1){
record[0]--;
return record[i] = 1;
}
record[0]--;
record[i]= find(map[i])+1;;
return record[i];
}
int main(){
int n;
cin>>n;
record[0] = n;
for(int i=1;i<=n;i++){
cin>>map[i];
}
int max=0;
for(int i=1;i<=n && record[0]>0;i++){
find(i);
if(record[i]>max){
max=record[i];
}
}
cout<<max<<endl;
int flag=1;
for(int i=1;i<=n;i++){
if(record[i]==max){
if(flag){
cout<<i;
flag=0;
}else{
cout<<" "<<i;
}
}
}
return 0;
}