답안 #602521

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
602521 2022-07-23T07:30:13 Z jophyyjh Job Scheduling (IOI19_job) C++14
100 / 100
243 ms 18748 KB
/**
 * What an interesting pratice contest problem! I could only solve the first 3
 * subtasks. (they're really trivial...) After that I searched online for an answer.
 * 
 * The idea is like "Chain Reactions" (Google Code Jam 2022 Qual.). Since a node can
 * only be chosen when its parent has been, we try to carefully merge leaf nodes into
 * their parent through a greedy approach. Previously, I tried too hard on
 * identifying the first / last selected node, which can be quite difficult when our
 * search base is the whole tree.
 * 
 * Each time, we try to find a node v with the smallest d[]/u[]. (This node need not
 * be a leaf.) We try to merge v into its parent p, i.e. u[p] += u[v], d[p] += d[v],
 * adjust the cost and let children of v have p as their direct parent. Why is
 * this greedy correct?
 * Although it could be difficult to determine which leaf is the last / which node
 * is the first, if v has the smallest d[]/u[], there exists a optimal schedule in
 * which v is built immediately after p is built. Simple argument of "exchange" can
 * prove this. In such case, we can just consider the time diff. (and add the
 * additional cost). Note that all children of v now have p as their direct parent
 * because once v and p are built, all children of v can start.
 * Learnt lots of stuff from this problem!
 * 
 * PS1  The solution above is inspired by Tutis (from Codeforces) in
 *      https://codeforces.com/blog/entry/68632.
 * PS2  When we apply our greedy strategy, the tree may be splited, forming a
 *      forest. We can add a pseudo root (the original -1 in parents[]) to simplify
 *      our code.
 * 
 * Time Complexity: O(n * log(n))
 * Implementation 2     (full solution, inspired by Tutis from Codeforces)
*/

#include <bits/stdc++.h>
#include "job.h"

typedef long long   ll;
typedef std::vector<int>    vec;

// DSU that can assign a value to each set
struct DSU {
    vec parents, rank, values;
    DSU(int n) {
        parents.resize(n);
        rank.resize(n);
        values.resize(n);
        for (int i = 0; i < n; i++)
            parents[i] = i, rank[i] = 1;
    }
    inline int find(int k) {
        if (parents[k] == k)
            return k;
        return parents[k] = find(parents[k]);
    }
    inline int& get_val(int k) {
        k = find(k);
        return values[k];
    }
    bool merge(int a, int b) {      // merge b into a
        a = find(a), b = find(b);
        if (a == b)
            return false;
        int val = values[a];
        if (rank[b] > rank[a])
            std::swap(a, b);
        rank[a] += rank[b], parents[b] = a, values[a] = val;
        return true;
    }
};


struct r_t {
    int node;
    double r;
};

inline bool operator<(const r_t& r1, const r_t& r2)     { return r1.r > r2.r; }

ll scheduling_cost(std::vector<int> _p, std::vector<int> _u, std::vector<int> _d) {
    int n = _p.size();
    std::vector<int> parents(n + 1), u(n + 1), d(n + 1);
    for (int i = 0; i < n; i++)
        parents[i + 1] = _p[i] + 1, u[i + 1] = _u[i], d[i + 1] = _d[i];
    parents[0] = -1, u[0] = d[0] = 0;       // pseudo node

    // Use dsu to maintain merged nodes
    DSU dsu(n + 1);
    dsu.get_val(0) = 0;
    std::vector<double> r(n + 1);
    std::priority_queue<r_t> pq;
    for (int i = 1; i <= n; i++) {
        dsu.get_val(i) = i, r[i] = double(d[i]) / u[i];
        pq.push(r_t{i, r[i]});
    }
    ll cost = 0;
    while (!pq.empty()) {
        r_t rt = pq.top();
        pq.pop();
        if (dsu.get_val(rt.node) != rt.node || r[rt.node] != rt.r)
            continue;
        int v = rt.node, p = dsu.get_val(parents[v]);
        // std::cerr << "(p,v): (" << p << ',' << v << "),\tpairs of (u,d) (" << u[p]
        //           << ',' << d[p] << ") (" << u[v] << ',' << d[v] << ")" << std::endl;
        cost -= ll(d[v]) * ll(u[p]);
        d[p] += d[v], u[p] += u[v], r[p] = double(d[p]) / u[p];
        dsu.merge(p, v);
        if (p > 0)
            pq.push(r_t{p, r[p]});
    }
    cost += ll(u[0]) * ll(d[0]);
    return cost;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 308 KB Output is correct
5 Correct 34 ms 4844 KB Output is correct
6 Correct 80 ms 9512 KB Output is correct
7 Correct 164 ms 15024 KB Output is correct
8 Correct 191 ms 18604 KB Output is correct
9 Correct 181 ms 18604 KB Output is correct
10 Correct 243 ms 18620 KB Output is correct
11 Correct 0 ms 212 KB Output is correct
12 Correct 189 ms 18600 KB Output is correct
13 Correct 146 ms 18720 KB Output is correct
14 Correct 179 ms 18580 KB Output is correct
15 Correct 120 ms 18580 KB Output is correct
16 Correct 159 ms 18748 KB Output is correct
17 Correct 222 ms 18600 KB Output is correct
18 Correct 182 ms 18616 KB Output is correct
19 Correct 111 ms 18620 KB Output is correct
20 Correct 98 ms 18736 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 300 KB Output is correct
3 Correct 1 ms 212 KB Output is correct
4 Correct 123 ms 17200 KB Output is correct
5 Correct 105 ms 17172 KB Output is correct
6 Correct 108 ms 17172 KB Output is correct
7 Correct 124 ms 17192 KB Output is correct
8 Correct 116 ms 17204 KB Output is correct
9 Correct 106 ms 17208 KB Output is correct
10 Correct 110 ms 17292 KB Output is correct
11 Correct 134 ms 17212 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 0 ms 212 KB Output is correct
3 Correct 1 ms 296 KB Output is correct
4 Correct 1 ms 316 KB Output is correct
5 Correct 5 ms 1344 KB Output is correct
6 Correct 114 ms 17820 KB Output is correct
7 Correct 110 ms 17724 KB Output is correct
8 Correct 136 ms 17808 KB Output is correct
9 Correct 125 ms 17828 KB Output is correct
10 Correct 1 ms 212 KB Output is correct
11 Correct 1 ms 340 KB Output is correct
12 Correct 4 ms 1236 KB Output is correct
13 Correct 5 ms 1340 KB Output is correct
14 Correct 122 ms 17716 KB Output is correct
15 Correct 125 ms 17828 KB Output is correct
16 Correct 121 ms 17844 KB Output is correct
17 Correct 114 ms 17832 KB Output is correct
18 Correct 122 ms 17720 KB Output is correct
19 Correct 114 ms 17724 KB Output is correct
20 Correct 123 ms 17724 KB Output is correct
21 Correct 109 ms 17724 KB Output is correct
22 Correct 107 ms 17756 KB Output is correct
23 Correct 125 ms 17832 KB Output is correct
24 Correct 120 ms 17716 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 194 ms 18600 KB Output is correct
3 Correct 211 ms 18620 KB Output is correct
4 Correct 190 ms 18724 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 1 ms 300 KB Output is correct
4 Correct 1 ms 300 KB Output is correct
5 Correct 1 ms 212 KB Output is correct
6 Correct 0 ms 300 KB Output is correct
7 Correct 1 ms 296 KB Output is correct
8 Correct 1 ms 212 KB Output is correct
9 Correct 0 ms 212 KB Output is correct
10 Correct 1 ms 212 KB Output is correct
11 Correct 1 ms 212 KB Output is correct
12 Correct 0 ms 300 KB Output is correct
13 Correct 1 ms 300 KB Output is correct
14 Correct 0 ms 212 KB Output is correct
15 Correct 1 ms 212 KB Output is correct
16 Correct 0 ms 212 KB Output is correct
17 Correct 1 ms 300 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 0 ms 212 KB Output is correct
2 Correct 1 ms 212 KB Output is correct
3 Correct 0 ms 212 KB Output is correct
4 Correct 1 ms 308 KB Output is correct
5 Correct 34 ms 4844 KB Output is correct
6 Correct 80 ms 9512 KB Output is correct
7 Correct 164 ms 15024 KB Output is correct
8 Correct 191 ms 18604 KB Output is correct
9 Correct 181 ms 18604 KB Output is correct
10 Correct 243 ms 18620 KB Output is correct
11 Correct 0 ms 212 KB Output is correct
12 Correct 189 ms 18600 KB Output is correct
13 Correct 146 ms 18720 KB Output is correct
14 Correct 179 ms 18580 KB Output is correct
15 Correct 120 ms 18580 KB Output is correct
16 Correct 159 ms 18748 KB Output is correct
17 Correct 222 ms 18600 KB Output is correct
18 Correct 182 ms 18616 KB Output is correct
19 Correct 111 ms 18620 KB Output is correct
20 Correct 98 ms 18736 KB Output is correct
21 Correct 1 ms 212 KB Output is correct
22 Correct 1 ms 300 KB Output is correct
23 Correct 1 ms 212 KB Output is correct
24 Correct 123 ms 17200 KB Output is correct
25 Correct 105 ms 17172 KB Output is correct
26 Correct 108 ms 17172 KB Output is correct
27 Correct 124 ms 17192 KB Output is correct
28 Correct 116 ms 17204 KB Output is correct
29 Correct 106 ms 17208 KB Output is correct
30 Correct 110 ms 17292 KB Output is correct
31 Correct 134 ms 17212 KB Output is correct
32 Correct 1 ms 212 KB Output is correct
33 Correct 0 ms 212 KB Output is correct
34 Correct 1 ms 296 KB Output is correct
35 Correct 1 ms 316 KB Output is correct
36 Correct 5 ms 1344 KB Output is correct
37 Correct 114 ms 17820 KB Output is correct
38 Correct 110 ms 17724 KB Output is correct
39 Correct 136 ms 17808 KB Output is correct
40 Correct 125 ms 17828 KB Output is correct
41 Correct 1 ms 212 KB Output is correct
42 Correct 1 ms 340 KB Output is correct
43 Correct 4 ms 1236 KB Output is correct
44 Correct 5 ms 1340 KB Output is correct
45 Correct 122 ms 17716 KB Output is correct
46 Correct 125 ms 17828 KB Output is correct
47 Correct 121 ms 17844 KB Output is correct
48 Correct 114 ms 17832 KB Output is correct
49 Correct 122 ms 17720 KB Output is correct
50 Correct 114 ms 17724 KB Output is correct
51 Correct 123 ms 17724 KB Output is correct
52 Correct 109 ms 17724 KB Output is correct
53 Correct 107 ms 17756 KB Output is correct
54 Correct 125 ms 17832 KB Output is correct
55 Correct 120 ms 17716 KB Output is correct
56 Correct 0 ms 212 KB Output is correct
57 Correct 194 ms 18600 KB Output is correct
58 Correct 211 ms 18620 KB Output is correct
59 Correct 190 ms 18724 KB Output is correct
60 Correct 1 ms 212 KB Output is correct
61 Correct 1 ms 212 KB Output is correct
62 Correct 1 ms 300 KB Output is correct
63 Correct 1 ms 300 KB Output is correct
64 Correct 1 ms 212 KB Output is correct
65 Correct 0 ms 300 KB Output is correct
66 Correct 1 ms 296 KB Output is correct
67 Correct 1 ms 212 KB Output is correct
68 Correct 0 ms 212 KB Output is correct
69 Correct 1 ms 212 KB Output is correct
70 Correct 1 ms 212 KB Output is correct
71 Correct 0 ms 300 KB Output is correct
72 Correct 1 ms 300 KB Output is correct
73 Correct 0 ms 212 KB Output is correct
74 Correct 1 ms 212 KB Output is correct
75 Correct 0 ms 212 KB Output is correct
76 Correct 1 ms 300 KB Output is correct
77 Correct 0 ms 212 KB Output is correct
78 Correct 1 ms 296 KB Output is correct
79 Correct 0 ms 212 KB Output is correct
80 Correct 0 ms 300 KB Output is correct
81 Correct 0 ms 212 KB Output is correct
82 Correct 0 ms 212 KB Output is correct
83 Correct 0 ms 212 KB Output is correct
84 Correct 1 ms 212 KB Output is correct
85 Correct 0 ms 300 KB Output is correct
86 Correct 0 ms 292 KB Output is correct
87 Correct 0 ms 212 KB Output is correct
88 Correct 3 ms 852 KB Output is correct
89 Correct 4 ms 980 KB Output is correct
90 Correct 8 ms 1376 KB Output is correct
91 Correct 32 ms 4932 KB Output is correct
92 Correct 70 ms 9384 KB Output is correct
93 Correct 167 ms 18588 KB Output is correct
94 Correct 170 ms 18492 KB Output is correct
95 Correct 189 ms 18608 KB Output is correct
96 Correct 180 ms 18488 KB Output is correct
97 Correct 163 ms 18452 KB Output is correct
98 Correct 178 ms 18596 KB Output is correct
99 Correct 167 ms 18468 KB Output is correct
100 Correct 165 ms 18504 KB Output is correct
101 Correct 221 ms 18712 KB Output is correct
102 Correct 127 ms 18492 KB Output is correct
103 Correct 175 ms 18588 KB Output is correct
104 Correct 194 ms 18620 KB Output is correct
105 Correct 133 ms 18600 KB Output is correct
106 Correct 112 ms 17968 KB Output is correct