답안 #781247

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
781247 2023-07-13T00:44:41 Z Programmer123 Islands (IOI08_islands) C++17
70 / 100
319 ms 131072 KB
#pragma GCC optimize("O3")

#include <bits/stdc++.h>

#define int long long int
signed dest[1000000];
signed length[1000000];
std::vector<signed> backEdges[1000000];
std::bitset<1000000> seen;
int bestPath[1000000];
#ifdef LOCAL
#define debug std::cout
#else
#define debug std::stringstream()
#endif

void findComponent(signed node, std::vector<signed> &data) {
    if (seen[node]) return;
    data.push_back(node);
    seen[node] = true;
    findComponent(dest[node], data);
    for (auto x: backEdges[node]) {
        findComponent(x, data);
    }
}

int treeSum(int node) {
    int sum = 0;
    for (auto x: backEdges[node]) {
        if (!seen[x]) {
            sum += length[x] + treeSum(x);
        }
    }
    return sum;
}

int bestSingle(int node) {
    if (bestPath[node] != 0) {
        return bestPath[node];
    }
    int best = 0;
    for (auto x: backEdges[node]) {
        if (!seen[x]) {
            best = std::max(best, length[x] + bestSingle(x));
        }
    }
    return bestPath[node] = best;
}

int bestDouble(int node) {
    int best = 0;
    int secondBest = 0;
    std::vector<int> back;
    for (auto x: backEdges[node]) {
        if (!seen[x]) {
            int score = length[x] + bestSingle(x);
            if (score > best) {
                secondBest = best;
                best = score;
            } else if (score > secondBest) {
                secondBest = score;
            }
        }
    }
    return best + secondBest;
}
//Best score, assuming doesn't pass through edge between start and end of cycle.
int bestA(signed root, signed cyclesize) {
    int best = 0;
    int current = 0;
    int bestBehind = 0;
    for (int i = 0; i < cyclesize; ++i) {
        best = std::max(best, bestSingle(root) + current + bestBehind);
        bestBehind = std::max(bestBehind, bestSingle(root) - current);
        current += length[root];
        root = dest[root];
    }
    return best;
}

int prev(int node) {
    for (auto x: backEdges[node]) {
        if (seen[x]) return x;
    }
    assert(false);
}
//Best score, assuming passes through edge between start and end of cycle
int bestB(signed root, signed cyclesize) {
    int current = 0;
//    std::vector<int> lengthForward;
//    for (int i = 0; i < cycle.size() - 1; ++i) {
//        lengthForward.push_back(current);
//        current += length[cycle[i]];
//    }
    current = 0;
    std::vector<int> lengthBackward;
    int node = prev(prev(root));
    for (int i = 0; i < cyclesize - 1; ++i) {
        lengthBackward.push_back(current);
        current += length[node];
        lengthBackward[i] += bestSingle(dest[node]);
        node = prev(node);
    }
//    node = prev(root);
//    for (int i = 0; i < cyclesize - 1; ++i) {
//        //lengthForward[i] += bestSingle(cycle[i]);
//        lengthBackward[i] += bestSingle(node);
//        node = prev(node);
//    }
    for (int i = 1; i < cyclesize - 1; ++i) {
        //lengthForward[i] = std::max(lengthForward[i], lengthForward[i - 1]);
        lengthBackward[i] = std::max(lengthBackward[i], lengthBackward[i - 1]);
    }
    int best = 0;
    int lengthForward = length[prev(root)];
    int bestForward = lengthForward + bestSingle(root);
    for (int i = 0; i < cyclesize - 1; ++i) {
        best = std::max(best, bestForward + lengthBackward[cyclesize - 2 - i]);
        lengthForward += length[root];
        bestForward = std::max(bestForward, lengthForward + bestSingle(root = dest[root]));
    }
    return best;
}

int componentSum(const std::vector<signed> &component) {
    for (auto x: component) {
        seen[x] = false;
    }
    signed root = component[0];
    while (!seen[root]) {
        seen[root] = true;
        root = dest[root];
    }
    for (auto x: component) {
        seen[x] = false;
    }
    signed cyclesize = 1;
    seen[root] = true;
    for (int x = dest[root]; x != root; x = dest[x]) {
        cyclesize++;
        seen[x] = true;
    }
    int best = 0;
    for (auto x: component) {
        best = std::max({best, bestDouble(x), bestSingle(x)});
    }
    best = std::max(best, bestA(root, cyclesize));
    best = std::max(best, bestB(root, cyclesize));
    for (auto x: component) {
        seen[x] = true;
    }
    return best;
}

signed main() {
#ifdef LOCAL
    freopen("INPUT", "r", stdin);
#endif
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int N;
    std::cin >> N;
    //seen = new bool[N];
    for (signed i = 0; i < N; ++i) {
        seen[i] = false;
        signed x, l;
        std::cin >> x >> l;
        x--;
        dest[i] = x;
        length[i] = l;
        backEdges[x].push_back(i);
    }
    int total = 0;
    for (int i = 0; i < N; ++i) {
        if (!seen[i]) {
            std::vector<signed> component;
            findComponent(i, component);
            total += componentSum(component);
        }
    }
    std::cout << total << std::endl;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 23764 KB Output is correct
2 Correct 14 ms 23732 KB Output is correct
3 Correct 16 ms 23892 KB Output is correct
4 Correct 12 ms 23764 KB Output is correct
5 Correct 13 ms 23764 KB Output is correct
6 Correct 13 ms 23716 KB Output is correct
7 Correct 13 ms 23712 KB Output is correct
8 Correct 13 ms 23780 KB Output is correct
9 Correct 14 ms 23764 KB Output is correct
10 Correct 13 ms 23764 KB Output is correct
11 Correct 13 ms 23716 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 23892 KB Output is correct
2 Correct 15 ms 23808 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 20 ms 23808 KB Output is correct
2 Correct 14 ms 24344 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 18 ms 24916 KB Output is correct
2 Correct 24 ms 28764 KB Output is correct
3 Correct 19 ms 24788 KB Output is correct
4 Correct 16 ms 24252 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 27 ms 30564 KB Output is correct
2 Correct 35 ms 31844 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 63 ms 36300 KB Output is correct
2 Correct 85 ms 53900 KB Output is correct
3 Correct 97 ms 70860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 97 ms 42428 KB Output is correct
2 Correct 140 ms 91456 KB Output is correct
3 Correct 181 ms 117940 KB Output is correct
4 Runtime error 157 ms 131072 KB Execution killed with signal 9
5 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 198 ms 47432 KB Output is correct
2 Runtime error 319 ms 131072 KB Execution killed with signal 9
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 204 ms 131072 KB Execution killed with signal 9
2 Halted 0 ms 0 KB -