use itertools::Itertools; use proconio::{input, marker::Usize1}; use std::{collections::VecDeque, iter::Peekable, slice::Iter}; fn main() { input! { n: usize, m: usize, d: u64, airplains: [(Usize1, Usize1, u64, u64, u64); m], } let mut counter = 0..; let nodes = vec_from_fn(2 * m, |_| counter.next().unwrap()); let source = counter.next().unwrap(); let sink = counter.next().unwrap(); let mut events = vec![vec![]; n]; let mut inst = MaxFlow::new(); for (i, &(u, v, p, q, w)) in airplains.iter().enumerate() { events[u].push((2 * p + 1, nodes[2 * i])); events[v].push((2 * (q + d), nodes[2 * i + 1])); inst.add_edge(2 * i, 2 * i + 1, w); } for e in &mut events { e.sort_unstable(); for ((_, x), (_, y)) in e.iter().copied().tuple_windows() { inst.add_edge(nodes[x], nodes[y], u64::MAX); } } if let Some(&(_, x)) = events[0].first() { inst.add_edge(source, x, u64::MAX); } if let Some(&(_, x)) = events[n - 1].last() { inst.add_edge(x, sink, u64::MAX); } let flow = inst.solve(counter.start, source, sink); println!("{flow}"); } fn vec_from_fn(len: usize, f: impl FnMut(usize) -> T) -> Vec { (0..len).map(f).collect() } #[derive(Default)] pub struct MaxFlow { edges: Vec, } impl MaxFlow { pub fn new() -> Self { Self::default() } pub fn add_edge(&mut self, src: usize, tar: usize, cap: u64) { self.edges.push(Edge { src, tar, cap }); self.edges.push(Edge { src: tar, tar: src, cap: 0, }); } pub fn solve(&mut self, n: usize, source: usize, sink: usize) -> u64 { let mut result = 0; let mut g = vec![vec![]; n]; for (i, e) in self.edges.iter().enumerate() { g[e.src].push(i); } loop { let mut level = vec![usize::MAX; n]; bfs(source, &mut level, &g, &self.edges); if level[sink] == usize::MAX { return result; } let mut used = vec![false; n]; let mut iter = g.iter().map(|g| g.iter().peekable()).collect::>(); while { let f = dfs( u64::MAX, source, sink, &mut used, &mut level, &mut iter, &mut self.edges, ); result += f; f != 0 } {} } } } fn bfs(source: usize, level: &mut [usize], g: &[Vec], edges: &[Edge]) { let mut queue = VecDeque::from([source]); level[source] = 0; while let Some(x) = queue.pop_front() { for &i in &g[x] { let y = edges[i].tar; if edges[i].cap == 0 || level[y] != usize::MAX { continue; } queue.push_back(y); level[y] = level[x] + 1; } } } fn dfs( f: u64, x: usize, sink: usize, used: &mut [bool], level: &mut [usize], iter: &mut [Peekable>], edges: &mut [Edge], ) -> u64 { if x == sink { return f; } used[x] = true; while let Some(&&i) = iter[x].peek() { let e = edges[i]; let y = e.tar; if used[y] || e.cap == 0 || level[x] >= level[y] { iter[x].next().unwrap(); continue; } let f = dfs(f.min(e.cap), y, sink, used, level, iter, edges); if f > 0 { edges[i].cap -= f; edges[i ^ 1].cap += f; return f; } iter[x].next().unwrap(); } level[x] = usize::MAX; 0 } #[derive(Clone, Copy, Debug)] struct Edge { src: usize, tar: usize, cap: u64, }