CF 613 D Kingdom and its Cities 题解

编程入门 行业动态 更新时间:2024-10-27 15:16:13

CF 613 D Kingdom and its Cities <a href=https://www.elefans.com/category/jswz/34/1769599.html style=题解"/>

CF 613 D Kingdom and its Cities 题解

CF 613 D Kingdom and its Cities 题解

所用知识虚树&贪心

假设只有一个询问,我们可以如下贪心:

每一个被占领的点的深度要尽可能小!

这是为什么呢?

感性理解一下就是一个占有的点可以分开更多的重要点,会往上传递更少的重要点。

这样我们可以用 d f s dfs dfs来实现。

但是这样的时间复杂度是 O ( n ∗ q ) O(n*q) O(n∗q)的显然不行。

我们可以发现有用的点只有重要的点,和它们两两间的 L C A LCA LCA。所以虚树搞一下就行了。

/*
{By GWj
*/
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define R(a) cin>>a
#define R2(a,b) cin>>a>>b
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
int n;
vector<int> g[100000+20];
int fa[100000+20][18],depth[100000+20],dfn[100000+20],cnt;
void dfs(int now=1,int pre=0,int deep=1){dfn[now]=++cnt;depth[now]=deep;fa[now][0]=pre;rb(i,1,17)fa[now][i]=fa[fa[now][i-1]][i-1];for(int it:g[now]){if(it!=pre)dfs(it,now,deep+1);}
}
int jump(int node,int dis){rl(i,17,0){if((dis>>i)&1) node=fa[node][i];}return node;
}
int lca(int u,int v){if(depth[u]>depth[v]) swap(u,v);v=jump(v,depth[v]-depth[u]);if(u==v) return u;rl(i,17,0){if(fa[u][i]!=fa[v][i]){u=fa[u][i];v=fa[v][i];}}return fa[v][0];
}
vector<int> vt[100000+20];
vector<int> key_nodes,used;
int imp[100000+20];
bool cmp(int A,int B){return dfn[A]<dfn[B];
}
map<mp,bool> exi;
mp run(int now){for(auto it:vt[now]){if(imp[now]&&imp[it]&&exi.find(II(now,it))!=exi.end()){return II(-1,-1);}}int cnt=0;int rest=0;for(auto it:vt[now]){mp tmp=run(it);rest+=tmp.FIR;cnt+=tmp.SEC;if(tmp.FIR==-1) return II(-1,-1);}if(imp[now]){rest+=cnt;cnt=1;}else{if(cnt>1){cnt=0;rest++;} }return II(rest,cnt);
}
int calc(){sort(ALL(key_nodes),cmp);stack<int> s;s.push(1);used.PB(1);for(auto it:key_nodes){if(it==1) continue;int las=s.top();int llc=lca(las,it);if(llc==las){s.push(it);}else{while(depth[s.top()]>depth[llc]){int z=s.top();s.pop();	if(depth[s.top()]>depth[llc])vt[s.top()].PB(z);else vt[llc].PB(z);}if(s.top()!=llc){used.PB(llc);s.push(llc);}s.push(it);}used.PB(it);}while(!s.empty()){int z=s.top();s.pop();if(!s.empty())vt[s.top()].PB(z);}int rest=run(1).FIR;return rest;
}
int main(){fastio;R(n);rb(i,2,n){int u,v;R2(u,v);g[u].PB(v);g[v].PB(u);exi[II(u,v)]=exi[II(v,u)]=1;}dfs();int q;R(q);while(q--){used.clear();int k;R(k);key_nodes.clear();rb(i,1,k){int key;R(key);imp[key]=1;key_nodes.PB(key);}cout<<calc()<<endl;for(auto it:used){imp[it]=0;vt[it].clear();}}return 0;
}

更多推荐

CF 613 D Kingdom and its Cities 题解

本文发布于:2024-02-25 02:40:14,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1697508.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:题解   CF   Cities   Kingdom

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!