제출 #1262222

#제출 시각아이디문제언어결과실행 시간메모리
1262222minhpkPastiri (COI20_pastiri)C++20
100 / 100
481 ms119676 KiB
#include <bits/stdc++.h>
using namespace std;
int a,b;
vector <int> z[500005];
vector <int> v;
int high[500005];
int par[500005][20];
int low[1000005];
bool check[500001];
bool cmp(int a,int b){
     return high[a]>high[b];
}
int up[500005];
void dfs(int i,int parent){

     for (auto p:z[i]){
          if (p==parent){
              continue;
          }
          high[p]=high[i]+1;
          par[p][0]=i;
          dfs(p,i);
          low[i]=min(low[i],low[p]+1);
     }
     if (check[i]){
         low[i]=0;
     }
}
void dfs1(int i,int parent ,int pre){
     int min1=pre,min2=pre,trace=0;
     if (check[i]){
         min1=min2=0;
         up[i]=0;
     }
     for (auto p:z[i]){
          if (p==parent){
              continue;
          }
          if (min1>low[p]+1){
              min1=low[p]+1;
              trace=p;
          }
     }
     for (auto p:z[i]){
          if (p==parent || p==trace){
              continue;
          }
          if (min2>low[p]+1){
              min2=low[p]+1;
          }
          up[p]=min1+1;
          dfs1(p,i,up[p]);
     }
     if (trace){
         up[trace]=min2+1;
         dfs1(trace,i,up[trace]);
     }

}
bool vis[500005];
int cnt[500005];
void bfs1(){
    queue<int> q;
    for (auto p:v){
         q.push(p);
         vis[p]=true;
         cnt[p]=0;
    }
    while (q.size()){
          int pos=q.front();
          q.pop();
          for (auto p:z[pos]){
               if (vis[p]){
                   continue;
               }
               vis[p]=true;
               cnt[p]=cnt[pos]+1;
               q.push(p);
          }
    }
}
vector <int> res;
int jump(int x){
    int org=x;
    for (int i=19;i>=0;i--){
         int nxt=par[x][i];
         if (cnt[nxt]==high[org]-high[nxt]){
             x=par[x][i];
         }
    }
    return x;
}

void bfs(int sta,int len){
     queue<pair<int,int>> q;
     q.push({sta,len});
     vis[sta]=true;
     while (q.size()){
          auto [pos,remain]=q.front();
          q.pop();
          if (remain==0){
             continue;
          }
          for (auto p:z[pos]){
               if (vis[p] || (low[p]!=remain-1 && up[p]!=remain-1)){
                   continue;
               }
               vis[p]=true;
               q.push({p,remain-1});
          }
     }
}
signed main()
{
//    freopen("test.txt", "r", stdin);
//    freopen("o2.out", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> a >> b;
    for (int i=1;i<a;i++){
         int x,y;
         cin >> x >> y;
         z[x].push_back(y);
         z[y].push_back(x);
    }
    for (int i=1;i<=a;i++){
         low[i]=1e9;
         up[i]=1e9;
    }
    for (int i=1;i<=b;i++){
         int x;
         cin >> x;
         check[x]=true;
         v.push_back(x);
    }
    high[0]=-1;
    par[1][0]=1;
    dfs(1,1);
    dfs1(1,1,1e9);
//    cout << up[4] << "\n";
    for (int j=1;j<=19;j++){
         for (int i=1;i<=a;i++){
              par[i][j]=par[par[i][j-1]][j-1];
         }
    }
    sort(v.begin(),v.end(),cmp);
    bfs1();
    memset(vis,false,sizeof vis);
//    cout << cnt[1] << "\n";
    for (auto p:v){
         if (vis[p]){
             continue;
         }
         int nxt=jump(p);
         //int nxt=p;
//         cout << p << " " << nxt << " " <<  high[p] << "\n";
         int len=high[p]-high[nxt];
         res.push_back(nxt);
         bfs(nxt,len);
    }
    cout << res.size() << "\n";
    for (auto p:res){
         cout << p << " ";
    }
    return 0;
}


/*
7 3 6
2 < 1
5 < 1
7 > 3
1 = 3
4 > 2
5 = 2
bab?a?c

*/

/*
5
10 9 3 6 1
3
2 1 2 4
1 2 4
1 2 2

*/

/*
8
01010101
10111000

*/

/*
freopen("test.txt", "r", stdin);
    freopen("o2.out", "w", stdout);
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...