#include <stdio.h> #include <string.h> #include <vector> #include <set> #include <algorithm> #include <iterator> using namespace std; vector<vector<int>> G; vector<vector<int>> G2; vector<vector<int>> G3; vector<vector<int>> silna_vec; vector<int> visited; vector<int> visited2; vector<int> NR; int nr = 1; int silne = 0; bool result_found = false; std::set<int> result; std::set<int> tmp, tmp1; void dfs(int v) { visited[v] = 1; for (int i = 0; i < G[v].size(); ++i) { int z = G[v][i]; if (!visited[z]) { visited[z] = 1; dfs(z); } } NR[nr] = v; nr++; } void dfs2(int v) { visited2[v] = 1; for (int i = 0; i < G2[v].size(); ++i) { int z = G2[v][i]; if (!visited2[z]) { silna_vec[silne].push_back(z); visited2[z] = 1; dfs2(z); } } } void dfs3(int v, vector<int>& path) { visited[v] = 1; for (int i = 0; i < G3[v].size(); ++i) { int z = G3[v][i]; if (z == path[0]) { if (!result_found) { result_found = true; result.insert(path.begin(), path.end()); } else { tmp.clear(); tmp.insert(path.begin(), path.end()); std::swap(tmp1, result); //result do tmp1; result.clear(); std::set_intersection(tmp.begin(), tmp.end(), tmp1.begin(), tmp1.end(), std::inserter(result, result.end())); } } else if (!visited[z]) { path.push_back(z); visited[z] = 1; dfs3(z, path); path.pop_back(); } } } int main() { int n, m; scanf("%d %d", &n, &m); G.resize(n + 1); G2.resize(n + 1); visited.resize(n + 1); visited2.resize(n + 1); silna_vec.resize(n + 1); NR.resize(n + 1); for (int i = 0; i < m; ++i) { int a, b; scanf("%d %d", &a, &b); G[a].push_back(b); G2[b].push_back(a); } for (int i = 1; i <= n; i++) if (visited[i] == false) dfs(i); for (int i = n; i >= 1; i--) if (visited2[NR[i]] == false) { dfs2(NR[i]); silna_vec[silne].push_back(NR[i]); silne++; } vector<int> idp; for (int i = 0; i < silne; ++i) { if (silna_vec[i].size() > 1) idp.push_back(i); } if (idp.size() == 0) { puts("NIE"); } else if(idp.size() > 1) { puts("0"); } else { vector<int>& v = silna_vec[idp[0]]; sort(v.begin(), v.end()); G3.resize(n + 1); visited.resize(0); visited.resize(n + 1); for (int i = 0; i < v.size(); ++i) visited[v[i]] = 1; for (int i = 0; i < v.size(); ++i) { int a = v[i]; for (int j = 0; j < G[a].size(); ++j) { int b = G[a][j]; if (visited[b]) G3[a].push_back(b); } } for (int i = 1; i < G3.size(); ++i) { if (G3[i].size() > 0) { visited.resize(0); visited.resize(n + 1); vector<int> path; path.push_back(i); dfs3(i, path); } } printf("%d\n", result.size()); for(auto vv: result) printf("%d ", vv); puts(""); } 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 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | #include <stdio.h> #include <string.h> #include <vector> #include <set> #include <algorithm> #include <iterator> using namespace std; vector<vector<int>> G; vector<vector<int>> G2; vector<vector<int>> G3; vector<vector<int>> silna_vec; vector<int> visited; vector<int> visited2; vector<int> NR; int nr = 1; int silne = 0; bool result_found = false; std::set<int> result; std::set<int> tmp, tmp1; void dfs(int v) { visited[v] = 1; for (int i = 0; i < G[v].size(); ++i) { int z = G[v][i]; if (!visited[z]) { visited[z] = 1; dfs(z); } } NR[nr] = v; nr++; } void dfs2(int v) { visited2[v] = 1; for (int i = 0; i < G2[v].size(); ++i) { int z = G2[v][i]; if (!visited2[z]) { silna_vec[silne].push_back(z); visited2[z] = 1; dfs2(z); } } } void dfs3(int v, vector<int>& path) { visited[v] = 1; for (int i = 0; i < G3[v].size(); ++i) { int z = G3[v][i]; if (z == path[0]) { if (!result_found) { result_found = true; result.insert(path.begin(), path.end()); } else { tmp.clear(); tmp.insert(path.begin(), path.end()); std::swap(tmp1, result); //result do tmp1; result.clear(); std::set_intersection(tmp.begin(), tmp.end(), tmp1.begin(), tmp1.end(), std::inserter(result, result.end())); } } else if (!visited[z]) { path.push_back(z); visited[z] = 1; dfs3(z, path); path.pop_back(); } } } int main() { int n, m; scanf("%d %d", &n, &m); G.resize(n + 1); G2.resize(n + 1); visited.resize(n + 1); visited2.resize(n + 1); silna_vec.resize(n + 1); NR.resize(n + 1); for (int i = 0; i < m; ++i) { int a, b; scanf("%d %d", &a, &b); G[a].push_back(b); G2[b].push_back(a); } for (int i = 1; i <= n; i++) if (visited[i] == false) dfs(i); for (int i = n; i >= 1; i--) if (visited2[NR[i]] == false) { dfs2(NR[i]); silna_vec[silne].push_back(NR[i]); silne++; } vector<int> idp; for (int i = 0; i < silne; ++i) { if (silna_vec[i].size() > 1) idp.push_back(i); } if (idp.size() == 0) { puts("NIE"); } else if(idp.size() > 1) { puts("0"); } else { vector<int>& v = silna_vec[idp[0]]; sort(v.begin(), v.end()); G3.resize(n + 1); visited.resize(0); visited.resize(n + 1); for (int i = 0; i < v.size(); ++i) visited[v[i]] = 1; for (int i = 0; i < v.size(); ++i) { int a = v[i]; for (int j = 0; j < G[a].size(); ++j) { int b = G[a][j]; if (visited[b]) G3[a].push_back(b); } } for (int i = 1; i < G3.size(); ++i) { if (G3[i].size() > 0) { visited.resize(0); visited.resize(n + 1); vector<int> path; path.push_back(i); dfs3(i, path); } } printf("%d\n", result.size()); for(auto vv: result) printf("%d ", vv); puts(""); } return 0; } |