#include <algorithm> #include <iostream> #include <tuple> #include <vector> using namespace std; namespace { class Impossible {}; class Solver { private: int n; vector<vector<int>> upper; vector<vector<int>> not_upper; vector<vector<int>> lower; vector<vector<int>> not_lower; public: Solver(int n_): n{n_}, upper(n), not_upper(n), lower(n), not_lower(n) { } void request(int a, int b, bool wants) { if (wants) { upper[a].emplace_back(b); lower[b].emplace_back(a); } else { not_upper[a].emplace_back(b); not_lower[b].emplace_back(a); } } void dfs(int v, vector<int> const& parent, vector<int>& visited, int time, vector<int>& all) const { if (parent[v] >= 0) return; if (visited[v] == time) return; visited[v] = time; all.emplace_back(v); for (int w: upper[v]) dfs(w, parent, visited, time, all); for (int w: lower[v]) dfs(w, parent, visited, time, all); } vector<int> solve() const { vector<int> parent(n, -1); int root = -1; for (int v = 0; v < n; ++v) { if (!upper[v].empty()) continue; if (!not_lower[v].empty()) continue; root = v; break; } if (root < 0) throw Impossible{}; vector<int> group(n, root); parent[root] = root; int done = 1; vector<int> visited(n, -1); int time = 0; while (done < n) { int start = time; for (int v = 0; v < n; ++v) { if (parent[v] >= 0) continue; if (visited[v] >= start) continue; vector<int> component; dfs(v, parent, visited, time, component); ++time; auto our_component = [&visited, v](int w) { return visited[w] == visited[v]; }; int r = -1; for (int w: component) { if (any_of(upper[w].begin(), upper[w].end(), our_component)) continue; if (any_of(not_lower[w].begin(), not_lower[w].end(), our_component)) continue; r = w; break; } if (r < 0) throw Impossible{}; ++done; parent[r] = group[r]; for (int w: component) group[w] = r; } } return parent; } }; } int main() { iostream::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; Solver solver(n); for (int i = 0; i < m; ++i) { int a, b; char c; cin >> a >> b >> c; solver.request(a-1, b-1, c == 'T'); } try { auto parent = solver.solve(); for (int i = 0; i < n; ++i) { if (parent[i] == i) cout << "0\n"; else cout << parent[i] + 1 << '\n'; } } catch (Impossible&) { cout << "NIE\n"; return 0; } return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | #include <algorithm> #include <iostream> #include <tuple> #include <vector> using namespace std; namespace { class Impossible {}; class Solver { private: int n; vector<vector<int>> upper; vector<vector<int>> not_upper; vector<vector<int>> lower; vector<vector<int>> not_lower; public: Solver(int n_): n{n_}, upper(n), not_upper(n), lower(n), not_lower(n) { } void request(int a, int b, bool wants) { if (wants) { upper[a].emplace_back(b); lower[b].emplace_back(a); } else { not_upper[a].emplace_back(b); not_lower[b].emplace_back(a); } } void dfs(int v, vector<int> const& parent, vector<int>& visited, int time, vector<int>& all) const { if (parent[v] >= 0) return; if (visited[v] == time) return; visited[v] = time; all.emplace_back(v); for (int w: upper[v]) dfs(w, parent, visited, time, all); for (int w: lower[v]) dfs(w, parent, visited, time, all); } vector<int> solve() const { vector<int> parent(n, -1); int root = -1; for (int v = 0; v < n; ++v) { if (!upper[v].empty()) continue; if (!not_lower[v].empty()) continue; root = v; break; } if (root < 0) throw Impossible{}; vector<int> group(n, root); parent[root] = root; int done = 1; vector<int> visited(n, -1); int time = 0; while (done < n) { int start = time; for (int v = 0; v < n; ++v) { if (parent[v] >= 0) continue; if (visited[v] >= start) continue; vector<int> component; dfs(v, parent, visited, time, component); ++time; auto our_component = [&visited, v](int w) { return visited[w] == visited[v]; }; int r = -1; for (int w: component) { if (any_of(upper[w].begin(), upper[w].end(), our_component)) continue; if (any_of(not_lower[w].begin(), not_lower[w].end(), our_component)) continue; r = w; break; } if (r < 0) throw Impossible{}; ++done; parent[r] = group[r]; for (int w: component) group[w] = r; } } return parent; } }; } int main() { iostream::sync_with_stdio(false); cin.tie(nullptr); int n, m; cin >> n >> m; Solver solver(n); for (int i = 0; i < m; ++i) { int a, b; char c; cin >> a >> b >> c; solver.request(a-1, b-1, c == 'T'); } try { auto parent = solver.solve(); for (int i = 0; i < n; ++i) { if (parent[i] == i) cout << "0\n"; else cout << parent[i] + 1 << '\n'; } } catch (Impossible&) { cout << "NIE\n"; return 0; } return 0; } |