답안 #559293

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
559293 2022-05-09T15:07:30 Z Redhood Pastiri (COI20_pastiri) C++14
31 / 100
1000 ms 134476 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 + 100;
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(now.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{
//            assert(shrt[v] != 0);
            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);
    }
    assert(k != 0);
    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 251 ms 119376 KB Output is correct
2 Correct 317 ms 134040 KB Output is correct
3 Correct 326 ms 134476 KB Output is correct
4 Correct 312 ms 129220 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 22100 KB Output is correct
2 Correct 13 ms 22100 KB Output is correct
3 Correct 646 ms 46428 KB Output is correct
4 Correct 629 ms 48580 KB Output is correct
5 Correct 924 ms 49520 KB Output is correct
6 Execution timed out 1091 ms 57216 KB Time limit exceeded
7 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 19 ms 21972 KB Output is correct
2 Correct 15 ms 21972 KB Output is correct
3 Correct 14 ms 21960 KB Output is correct
4 Correct 15 ms 21928 KB Output is correct
5 Correct 13 ms 22052 KB Output is correct
6 Correct 13 ms 21972 KB Output is correct
7 Correct 13 ms 21972 KB Output is correct
8 Correct 13 ms 21972 KB Output is correct
9 Correct 13 ms 21920 KB Output is correct
10 Correct 13 ms 21940 KB Output is correct
11 Correct 13 ms 21912 KB Output is correct
12 Correct 15 ms 21972 KB Output is correct
13 Correct 16 ms 21972 KB Output is correct
14 Correct 14 ms 22076 KB Output is correct
15 Correct 13 ms 21972 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 855 ms 51592 KB Output is correct
2 Correct 935 ms 57836 KB Output is correct
3 Correct 935 ms 60688 KB Output is correct
4 Execution timed out 1037 ms 56052 KB Time limit exceeded
5 Halted 0 ms 0 KB -