답안 #574439

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
574439 2022-06-08T15:01:38 Z piOOE Spring cleaning (CEOI20_cleaning) C++17
44 / 100
1000 ms 21176 KB
#include <bits/stdc++.h>

using namespace std;

#define sz(x) ((int)size(x))
#define all(x) begin(x), end(x)
#define trace(x) cout << #x << ": " << (x) << endl;

typedef long long ll;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());

int rand(int l, int r) { return (int) ((ll) rnd() % (r - l + 1)) + l; }

const int N = 200000, infI = 1e9 + 7;
const ll infL = 3e18;

vector<int> g[N];
ll dp[3][N];//LL???
int depth[N], parent[N];

void pull(int v) {
    dp[0][v] = 0;
    dp[1][v] = dp[2][v] = infL;
    if (sz(g[v]) <= 1) {
        //v is a leaf
        dp[1][v] = 1;
    } else {
        for (int to: g[v]) {
            if (to != parent[v]) {
                array<ll, 3> dq = {dp[0][v], dp[1][v], dp[2][v]};
                dp[0][v] = min({dq[2] + dp[2][to], dq[1] + dp[1][to]});
                dp[1][v] = min({dq[0] + dp[1][to], dq[2] + dp[1][to], dq[1] + dp[2][to]});
                dp[2][v] = min({dq[0] + dp[2][to], dq[2] + dp[2][to], dq[1] + dp[1][to]});
            }
        }
        dp[1][v] += 1;
        dp[2][v] += 2;
    }
}

void dfs(int v, int p) {
    if (p != -1) {
        depth[v] = depth[p] + 1;
    }
    parent[v] = p;
    dp[0][v] = 0;
    dp[1][v] = dp[2][v] = infL;
    if (sz(g[v]) <= 1) {
        //v is a leaf
        dp[1][v] = 1;
    } else {
        for (int to: g[v]) {
            if (to != p) {
                dfs(to, v);
                array<ll, 3> dq = {dp[0][v], dp[1][v], dp[2][v]};
                dp[0][v] = min({dq[2] + dp[2][to], dq[1] + dp[1][to]});
                dp[1][v] = min({dq[0] + dp[1][to], dq[2] + dp[1][to], dq[1] + dp[2][to]});
                dp[2][v] = min({dq[0] + dp[2][to], dq[2] + dp[2][to], dq[1] + dp[1][to]});
            }
        }
        dp[1][v] += 1;
        dp[2][v] += 2;
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, q;
    cin >> n >> q;
    int root = -1;
    for (int i = 0; i < n - 1; ++i) {
        int a, b;
        cin >> a >> b;
        --a, --b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    for (int i = 0; i < n; ++i) {
        if (sz(g[i]) > 1) {
            root = i;
            break;
        }
    }
    assert(root != -1);
    dfs(root, -1);
    if (*max_element(all(depth)) <= 18) {
        while (q--) {
            int D;
            cin >> D;
            vector<int> a(D);
            for (int i = 0; i < D; ++i) {
                cin >> a[i];
                --a[i];
            }
            sort(all(a));
            vector<int> b;
            int extra = 0;
            for (int i = 0; i < D;) {
                int j = i;
                while (j < D && a[i] == a[j])
                    ++j;
                if ((j - i) & 1) {
                    b.push_back(a[i]);
                    extra += j - i - 1;
                } else {
                    b.push_back(a[i]);
                    b.push_back(a[i]);
                    extra += j - i - 2;
                }
                i = j;
            }
            swap(a, b);
            D = sz(a);
            for (int i = 0; i < D; ++i) {
                g[a[i]].push_back(i + n);
            }
            for (int i = 0; i < D; ++i) {
                pull(i + n);
                if (i == D - 1 || a[i + 1] != a[i]) {
                    int x = a[i];
                    while (x != -1) {
                        pull(x);
                        x = parent[x];
                    }
                }
            }
            cout << (dp[0][root] >= infL ? -1 : dp[0][root] + extra) << '\n';
            for (int i = 0; i < D; ++i) {
                g[a[i]].pop_back();
                if (i == D - 1 || a[i + 1] != a[i]) {
                    int x = a[i];
                    while (x != -1) {
                        pull(x);
                        x = parent[x];
                    }
                }
            }
        }
    } else {
        while (q--) {
            int D;
            cin >> D;
            vector<int> a(D);
            for (int i = 0; i < D; ++i) {
                cin >> a[i];
                --a[i];
            }
            for (int i = 0; i < D; ++i) {
                g[a[i]].push_back(i + n);
            }
            dfs(root, -1);
            cout << (dp[0][root] >= infL ? -1 : dp[0][root]) << '\n';
            for (int i = 0; i < D; ++i) {
                g[a[i]].pop_back();
            }
        }
    }
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 5056 KB Output is correct
2 Execution timed out 1088 ms 6500 KB Time limit exceeded
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 98 ms 5716 KB Output is correct
2 Correct 97 ms 6016 KB Output is correct
3 Execution timed out 1086 ms 12608 KB Time limit exceeded
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 9172 KB Output is correct
2 Correct 19 ms 9172 KB Output is correct
3 Correct 52 ms 19032 KB Output is correct
4 Correct 68 ms 21176 KB Output is correct
5 Correct 45 ms 17696 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 249 ms 7044 KB Output is correct
2 Correct 156 ms 6516 KB Output is correct
3 Correct 227 ms 6228 KB Output is correct
4 Correct 267 ms 6868 KB Output is correct
5 Correct 230 ms 7028 KB Output is correct
6 Correct 272 ms 6964 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 99 ms 9348 KB Output is correct
2 Correct 169 ms 9308 KB Output is correct
3 Correct 136 ms 8304 KB Output is correct
4 Correct 160 ms 10688 KB Output is correct
5 Correct 168 ms 10692 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 1095 ms 11340 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 5056 KB Output is correct
2 Execution timed out 1088 ms 6500 KB Time limit exceeded
3 Halted 0 ms 0 KB -