답안 #219668

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
219668 2020-04-05T22:58:58 Z tatyam Islands (IOI08_islands) C++17
100 / 100
1679 ms 116572 KB
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
template<class T> using pq = priority_queue<T, vector<T>, greater<T>>;
const ll INF = 0x1fffffffffffffff;
#define overload3(a,b,c,d,...) d
#define all(a) begin(a), end(a)
#define rep1(n) for(int i = 0; i < n; i++)
#define rep2(i,n) for(int i = 0; i < n; i++)
#define rep3(i,a,b) for(int i = a; i < b; i++)
#define rep(...) overload3(__VA_ARGS__, rep3, rep2, rep1)(__VA_ARGS__)
#define each(i,a) for(auto&& i : a)
 
template<class T, class U> bool chmin(T& a, const U& b){ if(a > b){ a = b; return 1; } return 0; }
template<class T, class U> bool chmax(T& a, const U& b){ if(a < b){ a = b; return 1; } return 0; }
 
 


struct SlidMax{
    deque<pair<ll, int>> q;
    int low = 0, high = 0;
    ll pop(){
        ll ans = q[0].first;
        if(q.front().second == low++) q.pop_front();
        return ans;
    }
    void push(ll x){
        while(q.size() && q.back().first <= x) q.pop_back();
        q.emplace_back(x, high++);
    }
};
const int MAX = 1000000;
bool circle[MAX], used[MAX];
vector<pii> g[MAX];
ll d[MAX], cost1[MAX], cost2[MAX];
inline ll Diameter(int at){
    queue<int> q; // 6MB
    cost1[at] = 0;
    q.push(at);
    ll max = 0;
    int idx;
    while(q.size()){
        int at = q.front();
        q.pop();
        each(i, g[at]) if(cost1[i.first] == INF){
            cost1[i.first] = cost1[at] + i.second;
            if(chmax(max, cost1[i.first])) idx = i.first;
            q.push(i.first);
        }
    }
    cost2[idx] = 0;
    q.push(idx);
    while(q.size()){
        int at = q.front();
        q.pop();
        each(i, g[at]) if(cost2[i.first] == INF){
            cost2[i.first] = cost2[at] + i.second;
            chmax(max, cost2[i.first]);
            q.push(i.first);
        }
    }
    return max;
}
int main(){
    fill(cost1, cost1 + MAX, INF);
    fill(cost2, cost2 + MAX, INF);
    int n;
    scanf("%d", &n);
    rep(n){
        int a, b;
        scanf("%d%d", &a, &b);
        a--;
        g[i].emplace_back(a, b);
    }
    rep(n) g[g[i][0].first].emplace_back(i, g[i][0].second);
    each(i, g) i.shrink_to_fit();
    ll ans = 0;
    rep(n) if(!used[i]){
        int at = i;
        vector<int> list = {i};
        while(!used[at]){
            used[at] = 1;
            list.push_back(at);
            at = g[at][0].first;
        }
        each(i, list) used[i] = 0;
        int circle_size = 0;
        while(!circle[at]){
            circle[at] = 1;
            circle_size++;
            at = g[at][0].first;
        }
        used[at] = 1;
        list = {at};
        for(int i = 0; i < list.size(); i++){
            const int at = list[i];
            for(int j = 1; j < g[at].size(); j++){
                const int to = g[at][j].first;
                if(!used[to]){
                    used[to] = 1;
                    list.push_back(to);
                }
            }
        }
        while(list.size() > 1){
            const int at = list.back();
            if(!circle[at]) chmax(d[g[at][0].first], d[at] + g[at][0].second);
            list.pop_back();
        }
        ll max = Diameter(at);
        vector<ll> len(circle_size * 2 + 1); // 16MB
        rep(circle_size * 2){
            const int to = g[at][0].first;
            len[i + 1] = len[i] + g[at][0].second;
            at = to;
        }
        SlidMax sw; // 8MB?
        rep(circle_size - 1){
            at = g[at][0].first;
            sw.push(len[i + 1] + d[at]);
        }
        at = g[at][0].first;
        rep(circle_size){
            chmax(max, sw.pop() - len[i] + d[at]);
            sw.push(len[circle_size + i] + d[at]);
            at = g[at][0].first;
        }
        ans += max;
    }
    cout << ans << endl;
}

Compilation message

islands.cpp: In function 'int main()':
islands.cpp:97:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for(int i = 0; i < list.size(); i++){
                        ~~^~~~~~~~~~~~~
islands.cpp:99:30: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             for(int j = 1; j < g[at].size(); j++){
                            ~~^~~~~~~~~~~~~~
islands.cpp:70:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%d", &n);
     ~~~~~^~~~~~~~~~
islands.cpp:73:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
         scanf("%d%d", &a, &b);
         ~~~~~^~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 27 ms 39552 KB Output is correct
2 Correct 32 ms 39552 KB Output is correct
3 Correct 28 ms 39552 KB Output is correct
4 Correct 29 ms 39552 KB Output is correct
5 Correct 28 ms 39424 KB Output is correct
6 Correct 28 ms 39424 KB Output is correct
7 Correct 29 ms 39672 KB Output is correct
8 Correct 27 ms 39424 KB Output is correct
9 Correct 29 ms 39544 KB Output is correct
10 Correct 28 ms 39424 KB Output is correct
11 Correct 28 ms 39424 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 28 ms 39552 KB Output is correct
2 Correct 29 ms 39552 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 32 ms 39800 KB Output is correct
2 Correct 31 ms 39808 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 38 ms 40568 KB Output is correct
2 Correct 54 ms 42356 KB Output is correct
3 Correct 42 ms 41088 KB Output is correct
4 Correct 35 ms 40312 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 62 ms 43380 KB Output is correct
2 Correct 81 ms 45508 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 151 ms 52076 KB Output is correct
2 Correct 147 ms 51168 KB Output is correct
3 Correct 178 ms 55160 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 233 ms 60920 KB Output is correct
2 Correct 329 ms 75240 KB Output is correct
3 Correct 312 ms 68388 KB Output is correct
4 Correct 395 ms 84344 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 448 ms 89420 KB Output is correct
2 Correct 1240 ms 108692 KB Output is correct
3 Correct 439 ms 94200 KB Output is correct
4 Correct 587 ms 108712 KB Output is correct
5 Correct 583 ms 116572 KB Output is correct
6 Correct 1673 ms 106488 KB Output is correct
7 Correct 565 ms 114688 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 522 ms 99040 KB Output is correct
2 Correct 496 ms 99044 KB Output is correct
3 Correct 556 ms 107996 KB Output is correct
4 Correct 758 ms 87800 KB Output is correct
5 Correct 548 ms 111016 KB Output is correct
6 Correct 632 ms 105360 KB Output is correct
7 Correct 1679 ms 107872 KB Output is correct