이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
#define F first
#define S second
#define forn(i, n) for (int i = 0; i < int(n); i++)
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
pll dfs(vector<vector<int>>& tree, int v) {
ll child_sum = 0, subtree_sum = 0;
for (int w : tree[v]) {
pll p = dfs(tree, w);
child_sum += p.F;
subtree_sum += p.S;
}
ll salary = child_sum + 1;
return {salary, subtree_sum + salary};
}
int main() {
ios_base::sync_with_stdio(false);
cout << setprecision(12);
cin.tie(nullptr);
int n;
cin >> n;
vector<vector<int>> adj(n);
forn(v, n) {
int k; cin >> k;
forn(i, k) {
int u; cin >> u; u--;
adj[u].push_back(v);
}
}
ll ans = LLONG_MAX;
queue<int> q;
vector<bool> visited;
vector<vector<int>> tree;
stack<pair<int, bool>> s;
vector<ll> salary, subtree;
forn(root, n) {
visited.assign(n, false);
tree.assign(n, {});
q.push(root);
visited[root] = true;
int num_visited = 1;
while (!q.empty()) {
int v = q.front(); q.pop();
for (int w : adj[v]) {
if (visited[w])
continue;
tree[v].push_back(w);
q.push(w);
visited[w] = true;
num_visited++;
}
}
if (num_visited < n)
continue;
salary.assign(n, 0);
subtree.assign(n, 0);
s.emplace(root, false);
while (!s.empty()) {
auto p = s.top(); s.pop();
int v = p.F;
bool done = p.S;
if (done) {
salary[v] = 1;
for (int w : tree[v]) {
salary[v] += salary[w];
subtree[v] += subtree[w];
}
subtree[v] += salary[v];
} else {
s.emplace(v, true);
for (int w : tree[v])
s.emplace(w, false);
}
}
ans = min(ans, subtree[root]);
}
cout << ans << endl;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |