競プロ典型 003

https://atcoder.jp/contests/typical90/tasks/typical90_c

要は、木の径(+1)を求める問題ですね。

// Longest Circular Road
#![allow(non_snake_case)]

use std::collections::VecDeque;


//////////////////// library ////////////////////

fn read<T: std::str::FromStr>() -> T {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).ok();
    line.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace()
            .map(|e| e.parse().ok().unwrap()).collect()
}


//////////////////// Graph ////////////////////

type Node = usize;
type Edge = (Node, Node);
type Graph = Vec<Vec<Node>>;

fn read_edge() -> Edge {
    let v: Vec<usize> = read_vec();
    (v[0]-1, v[1]-1)
}

fn create_graph(edges: Vec<Edge>) -> Graph {
    let N = edges.len() + 1;
    let mut graph: Graph = vec![vec![]; N];
    for (A, B) in edges.into_iter() {
        graph[A].push(B);
        graph[B].push(A)
    }
    graph
}

const INF: i32 = 10000;

fn find_farthest_point(v0: Node, graph: &Graph) -> (Node, i32) {
    let N = graph.len();
    let mut q = VecDeque::new();
    q.push_back(v0);
    let mut dists: Vec<i32> = vec![INF; N];
    dists[v0] = 0;
    let mut v1 = v0;
    while let Some(v) = q.pop_front() {
        v1 = v;
        let d = dists[v];
        for &v1 in graph[v].iter() {
            if dists[v1] == INF {
                dists[v1] = d + 1;
                q.push_back(v1)
            }
        }
    }
    (v1, dists[v1])
}

fn diameter(graph: &Graph) -> i32 {
    let (v1, _) = find_farthest_point(0, &graph);
    let (_, d2) = find_farthest_point(v1, &graph);
    d2
}


//////////////////// process ////////////////////

fn read_input() -> Vec<Edge> {
    let N: usize = read();
    let edges: Vec<Edge> = (0..N-1).map(|_| read_edge()).collect();
    edges
}

fn F(edges: Vec<Edge>) -> i32 {
    let graph = create_graph(edges);
    diameter(&graph) + 1
}

fn main() {
    let edges = read_input();
    println!("{}", F(edges))
}