P7215 [JOISC2020] 首都]
P7215 [JOISC2020] 首都
考虑对于颜色
即对于颜色
考虑朴素的做法。具体地,对于颜色
用点分治维护此操作,以当前的分治中心为根在其子树内进行相同操作,但是当在统计过程中出现的颜色节点在当前分治中心的子树外,则直接退出,本次答案统计作废。因为若这个颜色节点在当前子树外,则它与当前分治中心的路径上必会经过上一级分治节点(即上一级分治中心的答案也会被统计在当前答案内),相当于上一级分治节点的颜色序列必包含在当前的分治中心的颜色序列中,即当前的答案只会相同或更劣。这一步操作较为关键,它能较大的优化统计答案的效率。
可以发现,虽然每次的统计仍然是
备注:有关点分治时间复杂度的证明:
- 分治中心为当前子树的重心
- 根据重心的性质,每进行一次分治操作,问题规模(子树大小)就会减小一半。说明点分治的递归次数为
级别。
另:点分治
本题代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int n,k;
int u,v;
int ans=1e9+10,res;
vector < int >edge[N],col[N];
int c[N];
int siz[N],f[N];
int rt;
queue<int>q;
int tag[N],c_tag[N],vis[N];
int stc[N],tp;
int maxsiz[N];
void getrt(int t,int fa,int _siz){
siz[t]=1,maxsiz[t]=0;;
for(auto v : edge[t]){
if(v==fa || vis[v])continue;
getrt(v,t,_siz);
siz[t]+=siz[v];
maxsiz[t]=max(maxsiz[t],siz[v]);
}
maxsiz[t]=max(maxsiz[t],_siz-siz[t]);
if(maxsiz[t]<maxsiz[rt])rt=t;
}
bool is_push(vector<int> &cl){
for(int i=0;i<cl.size();i++){
if(!tag[cl[i]])return 1; //若统计范围在当前子树外,避免本次统计
q.push(cl[i]);
}
res++;
return 0;
}
void dfs(int t,int fa){
f[t]=fa;
for(auto v:edge[t]){
if(v==fa || vis[v])continue;
dfs(v,t);
}
}
void calc(int t){
res=0;
while(!q.empty())q.pop();
c_tag[c[t]]=1;
if(is_push(col[c[t]]))return ;
dfs(t,t);
while(!q.empty()){
int u=q.front();
q.pop();
if(!c_tag[c[f[u]]]){
c_tag[c[f[u]]]=1;
if(is_push(col[c[f[u]]]))return ;
}
}
ans=min(ans,res);
}
void sign(int t,int fa){ //确定当前分治中心的子树范围
stc[++tp]=t,tag[t]=1;
for(auto v:edge[t]){
if(v==fa || vis[v])continue;
sign(v,t);
}
}
void solve(int t){
vis[t]=1,sign(t,t);
calc(t);
while(tp){
tag[stc[tp]]=c_tag[c[stc[tp]]]=0;
tp--;
}
for(auto v:edge[t]){
if(vis[v])continue;
rt=0;
getrt(v,t,siz[v]);
solve(rt);
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>k;
for(int i=1;i<n;i++){
cin>>u>>v;
edge[u].push_back(v);
edge[v].push_back(u);
}
for(int i=1;i<=n;i++){
cin>>c[i];
col[c[i]].push_back(i);
}
rt=0;
maxsiz[rt]=n;
getrt(1,1,n);
solve(rt);
cout<<ans-1<<'\n';//ans为连通块内最少颜色种类数
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效