// 有向 // 全体が強連結な時 // 二部グラフじゃないならok // 強連結じゃないなら? // 全部通るパスが存在するかつ最後以外については内部でokにできる // // Kが使えてないが? fn main() { input! { n: usize, m: usize, _k: usize, e: [(usize1, usize1); m], } let ans = if solve(n, e) {"Yes"} else {"No"}; println!("{ans}"); } fn solve(n: usize, e: Vec<(usize, usize)>) -> bool { let mut g = vec![vec![]; n]; for &(s, t) in e.iter() { g[s].push(t); } let (len, id) = strongly_connected_components(n, |v| g[v].iter().cloned()); if id[0] != 0 { return false; } let mut topo = vec![vec![]; len]; let mut deg = vec![0; len]; let mut dsu = DSU::new(2 * n); for &(s, t) in e.iter() { let a = id[s]; let b = id[t]; if a == b { dsu.unite(s, t + n); dsu.unite(t, s + n); } else { topo[a].push(b); deg[b] += 1; } } if deg.iter().filter(|d| **d == 0).count() > 1 { return false; } let mut v = deg.iter().rposition(|d| *d == 0).unwrap(); for i in 0..len { if v != i { return false; } for &u in topo[i].iter() { deg[u] -= 1; if deg[u] == 0 { v = v.max(u); } } } let mut size = vec![0; len]; let mut ok = false; for i in 0..n { let a = id[i]; size[a] += 1; if a + 1 < len { if !dsu.same(a, a + n) { return false; } } else { ok |= dsu.same(a, a + n); } } ok || size[len - 1] == 1 } // ---------- begin input macro ---------- // reference: https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8 #[macro_export] macro_rules! input { (source = $s:expr, $($r:tt)*) => { let mut iter = $s.split_whitespace(); input_inner!{iter, $($r)*} }; ($($r:tt)*) => { let s = { use std::io::Read; let mut s = String::new(); std::io::stdin().read_to_string(&mut s).unwrap(); s }; let mut iter = s.split_whitespace(); input_inner!{iter, $($r)*} }; } #[macro_export] macro_rules! input_inner { ($iter:expr) => {}; ($iter:expr, ) => {}; ($iter:expr, $var:ident : $t:tt $($r:tt)*) => { let $var = read_value!($iter, $t); input_inner!{$iter $($r)*} }; } #[macro_export] macro_rules! read_value { ($iter:expr, ( $($t:tt),* )) => { ( $(read_value!($iter, $t)),* ) }; ($iter:expr, [ $t:tt ; $len:expr ]) => { (0..$len).map(|_| read_value!($iter, $t)).collect::>() }; ($iter:expr, chars) => { read_value!($iter, String).chars().collect::>() }; ($iter:expr, bytes) => { read_value!($iter, String).bytes().collect::>() }; ($iter:expr, usize1) => { read_value!($iter, usize) - 1 }; ($iter:expr, $t:ty) => { $iter.next().unwrap().parse::<$t>().expect("Parse error") }; } // ---------- end input macro ---------- // ---------- begin scc ---------- pub fn strongly_connected_components(size: usize, graph: G) -> (usize, Vec) where G: Fn(usize) -> I, I: Iterator, { let mut ord = vec![0; size]; let mut res = vec![0; size]; let mut vertex = vec![]; let mut dfs = vec![]; let mut id = 0; for s in 0..size { if ord[s] > 0 { continue; } vertex.push(s); ord[s] = vertex.len(); dfs.push((s, graph(s))); while let Some((v, mut it)) = dfs.pop() { if let Some(u) = it.find(|u| ord[*u] == 0) { vertex.push(u); ord[u] = vertex.len(); dfs.extend([(v, it), (u, graph(u))]); } else { let low = graph(v).map(|u| ord[u]).min().unwrap_or(ord[v]); if low < ord[v] { ord[v] = low; continue; } let s = vertex.iter().rposition(|u| *u == v).unwrap(); for u in vertex.drain(s..) { ord[u] = !0; res[u] = id; } id += 1; } } } res.iter_mut().for_each(|p| *p = id - 1 - *p); (id, res) } // ---------- end scc ---------- //---------- begin union_find ---------- pub struct DSU { p: Vec, } impl DSU { pub fn new(n: usize) -> DSU { assert!(n < std::i32::MAX as usize); DSU { p: vec![-1; n] } } pub fn init(&mut self) { self.p.iter_mut().for_each(|p| *p = -1); } pub fn root(&self, mut x: usize) -> usize { assert!(x < self.p.len()); while self.p[x] >= 0 { x = self.p[x] as usize; } x } pub fn same(&self, x: usize, y: usize) -> bool { assert!(x < self.p.len() && y < self.p.len()); self.root(x) == self.root(y) } pub fn unite(&mut self, x: usize, y: usize) -> Option<(usize, usize)> { assert!(x < self.p.len() && y < self.p.len()); let mut x = self.root(x); let mut y = self.root(y); if x == y { return None; } if self.p[x] > self.p[y] { std::mem::swap(&mut x, &mut y); } self.p[x] += self.p[y]; self.p[y] = x as i32; Some((x, y)) } pub fn parent(&self, x: usize) -> Option { assert!(x < self.p.len()); let p = self.p[x]; if p >= 0 { Some(p as usize) } else { None } } pub fn sum(&self, mut x: usize, mut f: F) -> usize where F: FnMut(usize), { while let Some(p) = self.parent(x) { f(x); x = p; } x } pub fn size(&self, x: usize) -> usize { assert!(x < self.p.len()); let r = self.root(x); (-self.p[r]) as usize } } //---------- end union_find ----------