안 어려운 문제였는데 루트를 바꾼다는 생각을 못해서 1시간이나 써버렸어....
난 왜 트리의 루트를 1번으로 고정해놓고 생각할까
- #include<bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- vector<int>tree[200005];
- bool task[200005];
- ll DP[200005],dist[200005];
- int depth[200005];
- int dp[200005][20];
- void DFS(int cur,int p){
- DP[cur] = task[cur];
- for(int nxt:tree[cur]){
- if(nxt==p) continue;
- depth[nxt] = depth[cur]+1;
- dp[nxt][0] = cur;
- DFS(nxt,cur);
- DP[cur]+=DP[nxt];
- if(DP[nxt]) dist[cur]+=dist[nxt]+2;
- }
- }
- int LCA(int a,int b){
- if(depth[a]<depth[b]) swap(a,b);
- int d = depth[a] - depth[b];
- for(int i=0; d; i++){
- if(d&1) a = dp[a][i];
- d>>=1;
- }
- if(a!=b){
- for(int i=19; i>=0; i--){
- if(dp[a][i]==dp[b][i]) continue;
- a = dp[a][i]; b = dp[b][i];
- }
- a = dp[a][0];
- }
- return a;
- }
- void solve(){
- int n,k; cin>>n>>k;
- int x,y; cin>>x>>y;
- for(int i=1; i<=n; i++){
- task[i] = depth[i] = DP[i] = 0;
- dist[i] = 0;
- tree[i].clear();
- }
- task[x] = task[y] = 1;
- while(k--){
- int c; cin>>c;
- task[c] = 1;
- }
- k = 0;
- for(int i=1; i<=n; i++) k+=task[i];
- for(int i=1; i<n; i++){
- int a,b; cin>>a>>b;
- tree[a].emplace_back(b);
- tree[b].emplace_back(a);
- }
- DFS(1,0);
- for(int i=1; i<20; i++){
- for(int j=1; j<=n; j++) dp[j][i] = dp[dp[j][i-1]][i-1];
- }
- int lca = LCA(x,y);
- ll ans = 0;
- int pre = 0;
- if(lca==x || lca==y){
- if(lca==y) swap(x,y);
- while(y!=lca){
- ans+=dist[y];
- if(pre) ans-=dist[pre]+2;
- pre = y;
- ans++;
- y = dp[y][0];
- }
- ans+=dist[x];
- if(pre) ans-=dist[pre]+2;
- while(x!=1){
- if(DP[x]<k){
- ans+=2;
- int p = dp[x][0];
- ans+=dist[p] - (dist[x]+2);
- x = p;
- }
- else break;
- }
- }
- else{
- int pre = 0;
- while(x!=lca){
- ans+=dist[x];
- if(pre) ans-=dist[pre]+2;
- pre = x;
- ans++;
- x = dp[x][0];
- }
- int PRE = 0;
- while(y!=lca){
- ans+=dist[y];
- if(PRE) ans-=dist[PRE]+2;
- PRE = y;
- ans++;
- y = dp[y][0];
- }
- ans+=dist[lca];
- if(pre) ans-=dist[pre]+2;
- if(PRE) ans-=dist[PRE]+2;
- while(x!=1){
- if(DP[x]<k){
- ans+=2;
- int p = dp[x][0];
- ans+=dist[p] - (dist[x]+2);
- x = p;
- }
- else break;
- }
- }
- cout<<ans<<'\n';
- }
- int main(){
- ios_base::sync_with_stdio(false); cin.tie(NULL);
- int t = 1;
- cin >> t;
- while(t--) solve();
- }
색깔ㅋㅋ
나도 LCA 생각했는데 ㅋㅋ