답안 #793272

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
793272 2023-07-25T17:06:08 Z welleyth 통행료 (IOI18_highway) C++17
100 / 100
291 ms 16528 KB
#include <bits/stdc++.h>
#include "highway.h"

using namespace std;

constexpr int NN = 90000;

//#define int long long

typedef long long ll;

vector<pair<int,int>> g[NN];
vector<pair<int,int>> BFSTree[NN];
bool can[NN];
bool marked[NN];
bool wasL[NN],wasR[NN];
bool banned[NN];

void dfs(int v,int& c){
    marked[v] = true;
    c -= can[v];
    for(auto&[to,id] : g[v]){
        if(c > 0 && !marked[to]){
            dfs(to,c);
        }
    }
    return;
}

void dfsL(int v,int& c){
    if(wasL[v]){
        marked[v] = true;
        c -= can[v];
    }
    for(auto&[to,id] : BFSTree[v]){
        if(c > 0 && !marked[to] && wasL[to]){
            dfsL(to,c);
        }
    }
    return;
}

void dfsR(int v,int& c){
    if(wasR[v]){
        marked[v] = true;
        c -= can[v];
    }
    for(auto&[to,id] : BFSTree[v]){
        if(c > 0 && !marked[to] && wasR[to]){
            dfsR(to,c);
        }
    }
    return;
}

void find_pair(int N, std::vector<int> U, std::vector<int> V, int A, int B){
    int m = U.size();

    for(int i = 0; i < m; i++){
        g[U[i]].push_back(make_pair(V[i],i));
        g[V[i]].push_back(make_pair(U[i],i));
    }

    vector<int> w(m,0);
    ll minVal = ask(w);

    for(int i = 0; i < N; i++){
        can[i] = true;
    }

    int edgeID = -1;

    {
        vector<int> v;
        for(int i = 0; i < m; i++) v.push_back(i);
        bool s[m];
        for(int i = 0; i < m; i++){
            s[i] = 0;
        }
        while(v.size() > 1){
            vector<int> L,R;
            for(auto& id : v){
                if(R.size() < L.size())
                    R.push_back(id);
                else
                    L.push_back(id);
            }
            for(int i = 0; i < m; i++) w[i] = s[i];
            for(auto& id : L) w[id] = 1;
            ll val1 = ask(w);
            if(val1 > minVal){

                v = L;
            }
            else {
                for(auto& id : L) s[id] = true;
                v = R;
            }
        }
        assert(!v.empty());
        edgeID = v[0];
    }

    vector<int> BFSEdges;
    {
        bool used[N];
        memset(used,0,sizeof used);
        queue<int> q;
        q.push(U[edgeID]);
        used[U[edgeID]] = true;
        q.push(V[edgeID]);
        used[V[edgeID]] = true;
        BFSEdges.push_back(edgeID);

        while(!q.empty()){
            int v = q.front();
            q.pop();
            for(auto&[to,id] : g[v]){
                if(!used[to]){
                    used[to] = true;
                    q.push(to);
                    BFSEdges.push_back(id);
                    BFSTree[v].push_back(make_pair(to,id));
                    BFSTree[to].push_back(make_pair(v,id));
                }
            }
        }
    }

    {
        int u = U[edgeID], v = V[edgeID];
        banned[u] = banned[v] = true;
        queue<int> q;
        q.push(u);
        while(!q.empty()){
            int vv = q.front();
            wasL[vv] = true;
            can[vv] = true;
            q.pop();
            for(auto&[to,id] : BFSTree[vv]){
                if(!banned[to] && !wasL[to]){
                    wasL[to] = true;
                    can[to] = true;
                    q.push(to);
                }
            }
        }
        q.push(v);
        while(!q.empty()){
            int vv = q.front();
            q.pop();
            wasR[vv] = true;
            can[vv] = true;
            for(auto&[to,id] : BFSTree[vv]){
                if(!banned[to] && !wasR[to]){
                    wasR[to] = true;
                    can[to] = true;
                    q.push(to);
                }
            }
        }
    }

    bool notInBFSTRee[m];
    for(int i = 0; i < m; i++) notInBFSTRee[i] = true;
    for(auto& id : BFSEdges) notInBFSTRee[id] = false;

    int s,t;
    s = t = -1;

    {
        int root = U[edgeID];
        int cnt = 0;
        for(int i = 0; i < N; i++){
            if(wasL[i]){
                cnt += can[i];
            }
        }
        while(cnt > 1){
            for(int i = 0; i < N; i++) marked[i] = false;
            int c = cnt/2;
            dfsL(root,c);
            for(int i = 0; i < m; i++) w[i] = notInBFSTRee[i];
            for(int i = 0; i < N; i++){
                for(auto&[to,id] : g[i]){
                    if(marked[i] && !marked[to] && !banned[to])
                        w[id] = true;
                }
            }
            if(ask(w) > minVal){
                for(int i = 0; i < N; i++){
                    if(wasL[i] && marked[i])
                        can[i] = false;
                }
            } else {
                for(int i = 0; i < N; i++){
                    if(wasL[i] && !marked[i])
                        can[i] = false;
                }
            }

            cnt = 0;
            for(int i = 0; i < N; i++){
                if(wasL[i])
                    cnt += can[i];
            }
        }
        for(int i = 0; i < N; i++){
            if(wasL[i] && can[i])
                s = i;
        }
    }
    {
        int root = V[edgeID];
        int cnt = 0;
        for(int i = 0; i < N; i++){
            if(wasR[i])
                cnt += can[i];
        }
        while(cnt > 1){
            for(int i = 0; i < N; i++) marked[i] = false;
            int c = cnt/2;
            dfsR(root,c);
            for(int i = 0; i < m; i++) w[i] = notInBFSTRee[i];
            for(int i = 0; i < N; i++){
                for(auto&[to,id] : g[i]){
                    if(marked[i] && !marked[to] && !banned[to])
                        w[id] = true;
                }
            }
            if(ask(w) > minVal){
                for(int i = 0; i < N; i++){
                    if(wasR[i] && marked[i])
                        can[i] = false;
                }
            } else {
                for(int i = 0; i < N; i++){
                    if(wasR[i] && !marked[i])
                        can[i] = false;
                }
            }

            cnt = 0;
            for(int i = 0; i < N; i++){
                if(wasR[i])
                    cnt += can[i];
            }
        }
        for(int i = 0; i < N; i++){
            if(wasR[i] && can[i])
                t = i;
        }
    }

    answer(s,t);

    return;
}


# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 4560 KB Output is correct
2 Correct 2 ms 4560 KB Output is correct
3 Correct 2 ms 4548 KB Output is correct
4 Correct 2 ms 4560 KB Output is correct
5 Correct 3 ms 4536 KB Output is correct
6 Correct 2 ms 4560 KB Output is correct
7 Correct 2 ms 4432 KB Output is correct
8 Correct 2 ms 4540 KB Output is correct
9 Correct 2 ms 4560 KB Output is correct
10 Correct 2 ms 4432 KB Output is correct
11 Correct 2 ms 4540 KB Output is correct
12 Correct 2 ms 4560 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4560 KB Output is correct
2 Correct 14 ms 5480 KB Output is correct
3 Correct 181 ms 13732 KB Output is correct
4 Correct 182 ms 13856 KB Output is correct
5 Correct 148 ms 13956 KB Output is correct
6 Correct 157 ms 13844 KB Output is correct
7 Correct 177 ms 13880 KB Output is correct
8 Correct 134 ms 13884 KB Output is correct
9 Correct 163 ms 13884 KB Output is correct
10 Correct 180 ms 13908 KB Output is correct
11 Correct 140 ms 13512 KB Output is correct
12 Correct 174 ms 13376 KB Output is correct
13 Correct 147 ms 13408 KB Output is correct
14 Correct 156 ms 13960 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 12 ms 5564 KB Output is correct
2 Correct 24 ms 6724 KB Output is correct
3 Correct 42 ms 7752 KB Output is correct
4 Correct 85 ms 13776 KB Output is correct
5 Correct 106 ms 13972 KB Output is correct
6 Correct 100 ms 14948 KB Output is correct
7 Correct 88 ms 14576 KB Output is correct
8 Correct 90 ms 13992 KB Output is correct
9 Correct 90 ms 14152 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 4560 KB Output is correct
2 Correct 13 ms 5468 KB Output is correct
3 Correct 100 ms 11724 KB Output is correct
4 Correct 108 ms 13796 KB Output is correct
5 Correct 125 ms 13836 KB Output is correct
6 Correct 139 ms 13780 KB Output is correct
7 Correct 130 ms 13824 KB Output is correct
8 Correct 143 ms 13776 KB Output is correct
9 Correct 177 ms 13920 KB Output is correct
10 Correct 138 ms 13856 KB Output is correct
11 Correct 178 ms 13400 KB Output is correct
12 Correct 158 ms 14072 KB Output is correct
13 Correct 140 ms 13736 KB Output is correct
14 Correct 143 ms 13788 KB Output is correct
15 Correct 129 ms 13852 KB Output is correct
16 Correct 116 ms 13800 KB Output is correct
17 Correct 179 ms 13524 KB Output is correct
18 Correct 151 ms 13768 KB Output is correct
19 Correct 150 ms 13760 KB Output is correct
20 Correct 129 ms 13752 KB Output is correct
21 Correct 108 ms 14444 KB Output is correct
22 Correct 138 ms 14452 KB Output is correct
23 Correct 186 ms 14360 KB Output is correct
24 Correct 152 ms 14448 KB Output is correct
25 Correct 245 ms 16528 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 18 ms 5564 KB Output is correct
2 Correct 36 ms 5604 KB Output is correct
3 Correct 146 ms 14240 KB Output is correct
4 Correct 165 ms 14544 KB Output is correct
5 Correct 289 ms 15412 KB Output is correct
6 Correct 230 ms 15392 KB Output is correct
7 Correct 259 ms 15532 KB Output is correct
8 Correct 232 ms 15440 KB Output is correct
9 Correct 146 ms 11532 KB Output is correct
10 Correct 132 ms 11908 KB Output is correct
11 Correct 113 ms 12656 KB Output is correct
12 Correct 209 ms 14400 KB Output is correct
13 Correct 250 ms 14824 KB Output is correct
14 Correct 273 ms 15168 KB Output is correct
15 Correct 277 ms 15176 KB Output is correct
16 Correct 166 ms 12600 KB Output is correct
17 Correct 157 ms 14664 KB Output is correct
18 Correct 145 ms 14908 KB Output is correct
19 Correct 151 ms 14884 KB Output is correct
20 Correct 131 ms 14916 KB Output is correct
21 Correct 231 ms 15528 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 18 ms 5564 KB Output is correct
2 Correct 21 ms 5644 KB Output is correct
3 Correct 186 ms 14252 KB Output is correct
4 Correct 223 ms 14440 KB Output is correct
5 Correct 234 ms 14700 KB Output is correct
6 Correct 200 ms 15432 KB Output is correct
7 Correct 255 ms 14280 KB Output is correct
8 Correct 183 ms 14420 KB Output is correct
9 Correct 220 ms 14580 KB Output is correct
10 Correct 291 ms 15444 KB Output is correct
11 Correct 258 ms 15576 KB Output is correct
12 Correct 215 ms 15408 KB Output is correct
13 Correct 103 ms 12640 KB Output is correct
14 Correct 153 ms 11912 KB Output is correct
15 Correct 111 ms 12720 KB Output is correct
16 Correct 105 ms 11916 KB Output is correct
17 Correct 105 ms 12656 KB Output is correct
18 Correct 149 ms 12164 KB Output is correct
19 Correct 243 ms 14456 KB Output is correct
20 Correct 228 ms 14764 KB Output is correct
21 Correct 261 ms 15144 KB Output is correct
22 Correct 235 ms 15204 KB Output is correct
23 Correct 228 ms 15284 KB Output is correct
24 Correct 221 ms 15164 KB Output is correct
25 Correct 255 ms 15180 KB Output is correct
26 Correct 269 ms 15300 KB Output is correct
27 Correct 130 ms 14844 KB Output is correct
28 Correct 127 ms 14748 KB Output is correct
29 Correct 103 ms 15068 KB Output is correct
30 Correct 153 ms 14820 KB Output is correct
31 Correct 173 ms 14784 KB Output is correct
32 Correct 151 ms 14644 KB Output is correct
33 Correct 136 ms 15052 KB Output is correct
34 Correct 151 ms 14792 KB Output is correct
35 Correct 106 ms 14720 KB Output is correct
36 Correct 104 ms 14588 KB Output is correct
37 Correct 102 ms 14972 KB Output is correct
38 Correct 109 ms 14700 KB Output is correct
39 Correct 257 ms 15768 KB Output is correct
40 Correct 258 ms 15772 KB Output is correct
41 Correct 261 ms 15328 KB Output is correct
42 Correct 234 ms 15520 KB Output is correct