답안 #559225

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
559225 2022-05-09T14:15:31 Z Redhood Pastiri (COI20_pastiri) C++14
31 / 100
1000 ms 143972 KB
#include<bits/stdc++.h>

#define fi first
#define se second
#define sz(x) (int)(x).size()
#define pb push_back
#define mkp make_pair
using namespace std;

typedef long long ll;
typedef long double ld;
#define int long long
const int N = (int)5e5 + 10;
const int inf = 1e9;
vector < int > g[N];

int mnd[N];
int shrt[N], pred[N], h[N];

struct kek{
    int ans;
    int high;
    kek(){
        ans = 0;
        high = 1e9;
    }
};

kek state[N][2];

bool done[N][2];
void dfs(int v, int p, int H){
    h[v] = H;
    pred[v] = p;
    mnd[v] = (shrt[v] == 0 ? 0 : 1e9);
    for(auto &u : g[v]){
        if(u != p){
            dfs(u , v, H + 1);
            mnd[v] = min(mnd[v] , mnd[u] + 1);
        }
    }
}
int did[N][2];


bool better(kek a , kek b){
    if(a.ans == b.ans){
        return a.high < b.high;
    }
    return a.ans < b.ans;
}
void dfs1(int v, int fl){
    /// mnd[v];
    if(done[v][fl])
        return;
    done[v][fl] = 1;
    vector < int > small;
    for(auto &u : g[v]){
        if(u == pred[v])
            continue;
        if(mnd[u] + 1 > mnd[v]){
            dfs1(u, 1);
            state[v][fl].ans += state[u][1].ans;
            state[v][fl].high = min(state[v][fl].high, state[u][1].high);
        }else{
            small.pb(u);
        }
    }

    if(fl == 0){
        for(auto &u : small){
            bool t = 0;

            dfs1(u , 1);
            dfs1(u , 0);

            if(better(state[u][1], state[u][0]))
                t = 1;
            else
                t = 0;

            state[v][fl].ans += state[u][t].ans;
            state[v][fl].high = min(state[v][fl].high, state[u][t].high);
        }
    }else{
        /// two options
        kek now = state[v][fl];
        for(auto &u : small){
            dfs1(u , 1);
            dfs1(u , 0);
            now.ans += state[u][1].ans;
            now.high = min(state[v][fl].high, state[u][1].high);
        }
        /// another option is to cover by the current

        for(auto &u : small){
            bool t=0;
            if(better(state[u][1], state[u][0]))
                t = 1;
            else
                t = 0;
            state[v][1].ans += state[u][t].ans;
            state[v][1].high = min(state[v][1].high, state[u][t].high);
        }
        int x = h[v] - state[v][fl].high;

        bool put = 0;
        if(x != mnd[v]){
            if(shrt[v] == mnd[v]){
                state[v][fl].ans++, put = 1;
                state[v][fl].high = min(state[v][fl].high, h[v] - shrt[v]);
            }else
                state[v][fl].ans = inf;
        }


//        cerr << " lol " << v << ' ' << now.ans << ' ' << now.high << endl;

        if(better(state[v][fl], now)
        || (shrt[v]==0 && (now.high != h[v])) ){
            did[v][fl] = 1 + put;

        }else{
            state[v][fl] = now;
        }
    }
}
bool visited[N][2];
bool ans[N];
void get_ans(int v , int fl){
    assert(!visited[v][fl]);
    visited[v][fl] = 1;

    if(fl == 0){
        vector < int > small;
        for(auto &u : g[v]){
            if(u == pred[v])
                continue;
            if(mnd[u] + 1 > mnd[v]){
                get_ans(u, 1);
            }else{
                bool t = 0;
                if(better(state[u][1], state[u][0]))
                    t = 1;
                else
                    t = 0;
                get_ans(u , t);
            }
        }
    }else{
        if(did[v][fl] > 0){
            ans[v] = did[v][fl] - 1;
            for(auto &u : g[v]){
                if(u == pred[v])
                    continue;
                if(mnd[u] + 1 > mnd[v]){
                    get_ans(u, 1);
                }else{
                    bool t = 0;
                    if(better(state[u][1], state[u][0]))
                        t = 1;
                    else
                        t = 0;
                    get_ans(u , t);
                }
            }
        }else{
            for(auto &u : g[v]){
                if(u == pred[v])
                    continue;
                get_ans(u , 1);
            }
        }

    }
}
signed main(){
    ios_base::sync_with_stdio(0), cin.tie(0) , cout.tie(0);
    int n , k;
    cin >> n >> k;
    for(int i = 0; i < n - 1; ++i){
        int a , b;
        cin >> a >> b;
        --a, --b;
        g[a].pb(b);
        g[b].pb(a);
    }

    vector < int > o(k);
    for(auto &i : o)
        cin >> i, --i;
    queue < int > bfs;
    for(auto &u : o)
        bfs.push(u);

    fill(shrt , shrt + N , -1);

    for(auto &u : o)
        shrt[u] = 0;
    while(!bfs.empty()){
        int v = bfs.front();
        bfs.pop();
        for(auto &u : g[v]){
            if(shrt[u] == -1){
                shrt[u] = shrt[v] + 1;
                bfs.push(u);
            }
        }
    }

    dfs(0 , -1, 0);




    dfs1(0 , 1);

    get_ans(0 , 1);


//    cout << "fukk \n";

//    for(int i = 0; i < n; ++i){
//        if(done[i][0])
//        cout << i << ' ' << 0 << ' ' << state[i][0].ans << '\n';
//
//        if(done[i][1])
//        cout << i << ' ' << 1 << ' ' << state[i][1].ans << '\n';
//        cout << " NEW \n";
//
//    }


    vector < int > take;
    for(int i = 0; i < n; ++i){
        if(ans[i])
            take.pb(i);
    }
    assert(sz(take) == state[0][1].ans);

    cout << state[0][1].ans << endl;
    for(auto &u : take)
        cout << u + 1 << ' ';
    cout << endl;
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 230 ms 127960 KB Output is correct
2 Correct 302 ms 142928 KB Output is correct
3 Correct 298 ms 143972 KB Output is correct
4 Correct 314 ms 142104 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 17 ms 31996 KB Output is correct
2 Correct 17 ms 32084 KB Output is correct
3 Correct 601 ms 65056 KB Output is correct
4 Correct 572 ms 69844 KB Output is correct
5 Correct 818 ms 68172 KB Output is correct
6 Execution timed out 1034 ms 76056 KB Time limit exceeded
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 31828 KB Output is correct
2 Correct 18 ms 31744 KB Output is correct
3 Correct 17 ms 31852 KB Output is correct
4 Correct 16 ms 31764 KB Output is correct
5 Correct 17 ms 31900 KB Output is correct
6 Correct 16 ms 31752 KB Output is correct
7 Correct 15 ms 31828 KB Output is correct
8 Correct 16 ms 31828 KB Output is correct
9 Correct 16 ms 31828 KB Output is correct
10 Correct 15 ms 31844 KB Output is correct
11 Correct 17 ms 31748 KB Output is correct
12 Correct 14 ms 31700 KB Output is correct
13 Correct 15 ms 31828 KB Output is correct
14 Correct 15 ms 31956 KB Output is correct
15 Correct 15 ms 31788 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 775 ms 73480 KB Output isn't correct
2 Halted 0 ms 0 KB -