use std::{cmp::Reverse, collections::BinaryHeap}; const INF: usize = 1usize << 60; #[derive(Debug, Clone)] struct Dijkstra { n: usize, pathcosts: Vec>, pathcostsrev: Vec>, costs: Vec } impl Dijkstra { fn new(n: usize) -> Self { Self { n: n , pathcosts: vec![vec![]; n] , pathcostsrev: vec![vec![]; n] , costs: vec![INF; n] } } fn pusha2b(&mut self, a: usize, b: usize, cost: usize) { self.pathcosts[a].push((cost, b)); self.pathcostsrev[b].push((cost, a)); } fn get_cost(&self, idx: usize) -> usize { self.costs[idx] } fn solve(&mut self, startpoint: usize) { let mut que = BinaryHeap::new(); que.push(Reverse((0, startpoint))); self.costs[startpoint] = 0; while let Some(Reverse(p)) = que.pop() { let cost = p.0; let dest = p.1; if cost > self.costs[dest] { continue; } for &p2 in self.pathcosts[dest].iter() { if self.costs[dest] + p2.0 < self.costs[p2.1] { self.costs[p2.1] = self.costs[dest] + p2.0; que.push(Reverse((self.costs[p2.1], p2.1))); } } } } fn reconstruct(&self, startpoint: usize, endpoint: usize) -> Vec<(usize, usize)> { let mut ret = vec![]; if self.costs[endpoint] == INF { return ret; } let mut current = endpoint; while current != startpoint { for &(cost, u) in self.pathcostsrev[current].iter() { if self.costs[current] == self.costs[u] + cost { let prev = current; current = u; ret.push((current, prev)); break; } } } ret.reverse(); ret } } fn main() { let mut n = String::new(); std::io::stdin().read_line(&mut n).ok(); let n: usize = n.trim().parse().unwrap(); let mut r = String::new(); std::io::stdin().read_line(&mut r).ok(); let r: Vec = r.trim().split_whitespace().map(|s| s.parse::().unwrap()-1).collect(); let mut dijkstra = Dijkstra::new(n); for i in 0..n-1 { dijkstra.pusha2b(i, r[i], 1); dijkstra.pusha2b(i+1, i, 0); } dijkstra.solve(0); println!("{}", dijkstra.get_cost(n-1)); }