답안 #262232

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
262232 2020-08-12T13:53:00 Z evpipis Islands (IOI08_islands) C++11
100 / 100
1293 ms 131072 KB
#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef pair<int, int> ii;

const int len = 1e6+5;
int deg[len], n, ccs;
ii par[len];
ll dep[len], best[len];
ll val[2*len], pref[2*len];
vector<int> order[len];
vector<ii> adj[len];

void dfs1(int u, int col){
    while (deg[u] == 2){
        deg[u] = 1;
        order[col].pb(u);

        u = par[u].fi;
    }
}

void find_spec(){
    queue<int> myq;
    for (int i = 1; i <= n; i++){
        deg[i] = adj[i].size();
        if (deg[i] == 1)
            myq.push(i);
    }

    while (!myq.empty()){
        int u = myq.front(), p = par[u].fi;
        myq.pop();

        deg[p]--, deg[u]--;
        if (deg[p] == 1)
            myq.push(p);
    }

    ccs = 0;
    for (int i = 1; i <= n; i++)
        if (deg[i] == 2)
            dfs1(i, ccs++);
}

ll dfs2(int st){
    vector<int> vec;
    stack<int> mys;
    mys.push(st);
    while (!mys.empty()){
        int u = mys.top();
        mys.pop();

        vec.pb(u);

        for (auto v: adj[u])
            if (v.fi != par[u].fi && !deg[v.fi])
                mys.push(v.fi);
    }

    ll ans = 0;
    reverse(vec.begin(), vec.end());
    for (auto u: vec){
        ll mx1 = 0, mx2 = 0;

        for (auto v: adj[u]){
            if (v.fi == par[u].fi || deg[v.fi])
                continue;

            dep[u] = max(dep[u], dep[v.fi]+v.se);

            if (dep[v.fi]+v.se > mx1)
                swap(mx1, mx2), mx1 = dep[v.fi]+v.se;
            else if (dep[v.fi]+v.se > mx2)
                mx2 = dep[v.fi]+v.se;
        }

        ans = max(ans, mx1+mx2);
    }

    return ans;
}

void find_diam(){
    for (int i = 0; i < ccs; i++)
        for (auto u: order[i])
            best[i] = max(best[i], dfs2(u));
}

ll path(vector<int> &vec){
    ll ans = 0;

    int m = vec.size();
    for (int i = 0; i < 2*m; i++)
        val[i] = dep[vec[i%m]];
    for (int i = 0; i < 2*m-1; i++)
        pref[i+1] = pref[i]+par[vec[i%m]].se;

    deque<int> deq;
    for (int i = 0; i < 2*m; i++){
        while (!deq.empty() && i-deq.front()+1 > m)
            deq.pop_front();

        if (!deq.empty())
            ans = max(ans, pref[i]+val[i] + val[deq.front()]-pref[deq.front()]);

        while (!deq.empty() && val[i]-pref[i] >= val[deq.back()]-pref[deq.back()])
            deq.pop_back();
        deq.push_back(i);
    }

    return ans;
}

void find_path(){
    for (int i = 0; i < ccs; i++)
        best[i] = max(best[i], path(order[i]));
}

int main(){
    scanf("%d", &n);
    for (int i = 1; i <= n; i++){
        int p, c;
        scanf("%d %d", &p, &c);
        adj[i].pb(mp(p, c));
        adj[p].pb(mp(i, c));
        par[i] = mp(p, c);
    }

    find_spec();

    find_diam();

    find_path();

    ll ans = 0;
    for (int i = 0; i < ccs; i++)
        ans += best[i];
    printf("%lld\n", ans);
    return 0;
}

Compilation message

islands.cpp: In function 'int main()':
islands.cpp:126:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  126 |     scanf("%d", &n);
      |     ~~~~~^~~~~~~~~~
islands.cpp:129:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  129 |         scanf("%d %d", &p, &c);
      |         ~~~~~^~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 30 ms 47368 KB Output is correct
2 Correct 28 ms 47360 KB Output is correct
3 Correct 31 ms 47480 KB Output is correct
4 Correct 29 ms 47360 KB Output is correct
5 Correct 29 ms 47360 KB Output is correct
6 Correct 30 ms 47352 KB Output is correct
7 Correct 31 ms 47360 KB Output is correct
8 Correct 28 ms 47360 KB Output is correct
9 Correct 30 ms 47352 KB Output is correct
10 Correct 28 ms 47360 KB Output is correct
11 Correct 29 ms 47360 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 29 ms 47360 KB Output is correct
2 Correct 30 ms 47360 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 29 ms 47480 KB Output is correct
2 Correct 32 ms 47640 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 42 ms 48248 KB Output is correct
2 Correct 56 ms 50040 KB Output is correct
3 Correct 42 ms 48760 KB Output is correct
4 Correct 34 ms 47872 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 60 ms 51064 KB Output is correct
2 Correct 85 ms 53704 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 140 ms 59636 KB Output is correct
2 Correct 166 ms 61324 KB Output is correct
3 Correct 187 ms 67564 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 249 ms 70204 KB Output is correct
2 Correct 320 ms 83236 KB Output is correct
3 Correct 423 ms 85264 KB Output is correct
4 Correct 430 ms 98928 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 500 ms 110160 KB Output is correct
2 Correct 1042 ms 119780 KB Output is correct
3 Correct 509 ms 94152 KB Output is correct
4 Correct 634 ms 116140 KB Output is correct
5 Correct 682 ms 117400 KB Output is correct
6 Correct 1198 ms 105292 KB Output is correct
7 Correct 732 ms 127848 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 529 ms 102276 KB Output is correct
2 Correct 542 ms 102272 KB Output is correct
3 Correct 850 ms 131072 KB Output is correct
4 Correct 762 ms 109976 KB Output is correct
5 Correct 613 ms 118592 KB Output is correct
6 Correct 566 ms 105768 KB Output is correct
7 Correct 1293 ms 104496 KB Output is correct