$O(nm)$
각 컴퓨터마다 DFS 돌려서 해킹될 컴퓨터를 센다.
#include<cstdio> #include<vector> using namespace std; const int MXN = 1e4; vector<int> adj[MXN + 1]; int vis[MXN + 1], n, m, x, y, cnt[MXN + 1], res; void f(int h, int r) { if (vis[h] == r) return; vis[h] = r; for (auto it : adj[h]) f(it, r); cnt[r]++; } int main() { for (scanf("%d%d", &n, &m); m--;) { scanf("%d%d", &x, &y); adj[y].push_back(x); } for (int i = 1; i <= n; i++) { f(i, i); if (res < cnt[i]) res = cnt[i]; } for (int i = 1; i <= n; i++) if (res == cnt[i]) printf("%d ", i); return 0; }
$O(m\lg m+n^2)$
SCC를 구한 다음 DFS를 한다.
#include<cstdio> #include<vector> #include<algorithm> using namespace std; const int MXN = 1e4; int n, m, x, y, vis[MXN + 1], maxi, s, sz, flag[MXN + 1], num[MXN + 1], res[MXN + 1]; vector<int> adj[2][MXN + 1], nadj[MXN + 1], v, tv; void f(int h, int t) { if (vis[h] ^ t) return; vis[h] = !t; for (auto it : adj[t][h]) f(it, t); v.push_back(h); } void g(int h, int t) { if (vis[h] == t) return; vis[h] = t; for (auto it : nadj[h]) g(it, t); s += num[h]; } int main() { for (scanf("%d%d", &n, &m); m--;) { scanf("%d%d", &x, &y); adj[0][y].push_back(x); adj[1][x].push_back(y); } for (int i = 1; i <= n; i++) f(i, 0); tv = v; for (int i = tv.size(); i--;) if (vis[tv[i]]) { v.clear(); f(tv[i], 1); num[++sz] = v.size(); for (auto h : v) for (auto t : adj[1][h]) if (flag[t]) nadj[flag[t]].push_back(sz); for (auto it : v) flag[it] = sz; } for (int i = 1; i <= sz; i++) { sort(nadj[i].begin(), nadj[i].end()); nadj[i].erase(unique(nadj[i].begin(), nadj[i].end()), nadj[i].end()); } for (int i = 1; i <= sz; i++) { s = 0; g(i, i); for (int j = 1; j <= n; j++) if (flag[j] == i) res[j] = s; maxi = max(maxi, s); } for (int i = 1; i <= n; i++) if (maxi == res[i]) printf("%d ", i); return 0; }
댓글 없음 :
댓글 쓰기