This documentation is automatically generated by online-judge-tools/verification-helper
// verification-helper: PROBLEM https://atcoder.jp/contests/abc291/tasks/abc291_e
#include "src/cpp-template/header/size-alias.hpp"
#include "src/graph/class/edge/edge.hpp"
#include "src/graph/class/dynamic-graph.hpp"
#include "src/graph/topological-ordering/lexical-order-topological-sort.hpp"
#include <functional>
#include <iostream>
namespace luz {
void main_() {
using edge = Edge< usize >;
using graph = DynamicGraph< edge >;
usize n, m;
std::cin >> n >> m;
graph g(n);
while (m--) {
usize t, f;
std::cin >> t >> f;
g.add_directed_edge(t - 1, f - 1);
}
auto ord =
lexical_order_topological_sort< graph,
std::greater< usize > >(g);
auto rev =
lexical_order_topological_sort< graph, std::less< usize > >(
g);
if (ord == rev) {
std::cout << "Yes" << std::endl;
std::vector< usize > ans(n);
for (usize i = 0; i < n; i++) {
ans[ord[i]] = i + 1;
}
for (usize i = 0; i < n; i++) {
std::cout << ans[i] << (i + 1 == n ? '\n' : ' ');
}
} else {
std::cout << "No" << std::endl;
}
}
} // namespace luz
int main() {
luz::main_();
}
#line 1 "test/atcoder/abc291_e.test.cpp"
// verification-helper: PROBLEM https://atcoder.jp/contests/abc291/tasks/abc291_e
#line 2 "src/cpp-template/header/size-alias.hpp"
#include <cstddef>
namespace luz {
using isize = std::ptrdiff_t;
using usize = std::size_t;
}
#line 2 "src/graph/class/edge/edge.hpp"
#line 4 "src/graph/class/edge/edge.hpp"
namespace luz {
template < typename T >
struct Edge {
using cost_type = T;
usize from, to;
T cost;
usize id;
Edge() = default;
Edge(usize f, usize t, T c, usize i) : from(f), to(t), cost(c), id(i) {}
};
} // namespace luz
#line 2 "src/graph/class/dynamic-graph.hpp"
#line 4 "src/graph/class/dynamic-graph.hpp"
#include <cassert>
#include <vector>
namespace luz {
template < typename Edge >
class DynamicGraph {
using Edges = std::vector< Edge >;
protected:
std::vector< Edges > g;
usize edge_count;
public:
using cost_type = typename Edge::cost_type;
DynamicGraph() = default;
explicit DynamicGraph(usize n): g(n), edge_count(0) {}
usize size() const {
return g.size();
}
void add_directed_edge(usize from, usize to, cost_type cost = 1) {
g[from].emplace_back(from, to, cost, edge_count++);
}
void add_undirected_edge(usize u, usize v, cost_type cost = 1) {
assert(u != v);
g[u].emplace_back(u, v, cost, edge_count);
g[v].emplace_back(v, u, cost, edge_count++);
}
Edges operator[](const usize &v) {
return g[v];
}
const Edges operator[](const usize &v) const {
return g[v];
}
};
} // namespace luz
#line 2 "src/graph/topological-ordering/lexical-order-topological-sort.hpp"
#include <queue>
#line 5 "src/graph/topological-ordering/lexical-order-topological-sort.hpp"
// usage
// - min: lexical_order_topological_sort< G, std::greater< usize > >(g);
// - max: lexical_order_topological_sort< G, std::less< usize > >(g);
// !!! it returns {} if G is disconnected or not DAG.
namespace luz {
template < class G, class Compare >
std::vector< usize > lexical_order_topological_sort(const G &g) {
usize n = g.size();
std::vector< usize > indegrees(n);
for (usize v = 0; v < n; v++) {
for (auto &&e: g[v]) {
indegrees[e.to]++;
}
}
std::priority_queue< usize, std::vector< usize >, Compare > pq;
for (usize v = 0; v < n; v++) {
if (indegrees[v]) continue;
pq.emplace(v);
}
std::vector< usize > result;
result.reserve(n);
while (not pq.empty()) {
auto v = pq.top();
pq.pop();
result.emplace_back(v);
for (auto &&e: g[v]) {
if (--indegrees[e.to]) continue;
pq.emplace(e.to);
}
}
if (result.size() != n) {
return {};
}
return result;
}
} // namespace luz
#line 7 "test/atcoder/abc291_e.test.cpp"
#include <functional>
#include <iostream>
namespace luz {
void main_() {
using edge = Edge< usize >;
using graph = DynamicGraph< edge >;
usize n, m;
std::cin >> n >> m;
graph g(n);
while (m--) {
usize t, f;
std::cin >> t >> f;
g.add_directed_edge(t - 1, f - 1);
}
auto ord =
lexical_order_topological_sort< graph,
std::greater< usize > >(g);
auto rev =
lexical_order_topological_sort< graph, std::less< usize > >(
g);
if (ord == rev) {
std::cout << "Yes" << std::endl;
std::vector< usize > ans(n);
for (usize i = 0; i < n; i++) {
ans[ord[i]] = i + 1;
}
for (usize i = 0; i < n; i++) {
std::cout << ans[i] << (i + 1 == n ? '\n' : ' ');
}
} else {
std::cout << "No" << std::endl;
}
}
} // namespace luz
int main() {
luz::main_();
}