社区讨论
萌新初学树启求助复杂度
CF1009FDominant Indices参与者 5已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @mll7ddsq
- 此快照首次捕获于
- 2026/02/14 02:10 5 天前
- 此快照最后确认于
- 2026/02/17 10:20 前天
呃,启发式合并众所周知是带个萝卜的
考虑这题的这么一个实现
CPP#include<bits/stdc++.h>
using namespace std;
vector<int>ve[1000005];
int lf[1000005];
vector<int>lst[1000005];
int ans[1000005];
int mx[1000005];
bool flg[1000005];
void dfs(int x,int fa){
bool is=0;
int mxx=0,xb;
for(int i=0;i<ve[x].size();i++){
if(ve[x][i]==fa)continue;
dfs(ve[x][i],x);
is=1;
if(mxx<lst[lf[ve[x][i]]].size()){
xb=ve[x][i];
mxx=lst[lf[ve[x][i]]].size();
}
}
if(is){
lf[x]=lf[xb];
lst[lf[x]].push_back(1);
ans[x]=ans[lf[x]]+1;
mx[x]=mx[lf[x]];
if(mx[x]==1)ans[x]=0;
for(int i=0;i<ve[x].size();i++){
if(lf[ve[x][i]]==lf[x])continue;
for(int j=lst[lf[ve[x][i]]].size()-1;j>=0;j--){
int qwq=lst[lf[ve[x][i]]].size()-j;
qwq=lst[lf[x]].size()-qwq;
qwq--;
lst[lf[x]][qwq]+=lst[lf[ve[x][i]]][j];
if(lst[lf[x]][qwq]>mx[x])
mx[x]=lst[lf[x]][qwq],ans[x]=((int)(lst[lf[x]].size()-qwq))-1;
else if(lst[lf[x]][qwq]==mx[x]&&((int)(lst[lf[x]].size()-qwq))-1<ans[x])
ans[x]=((int)(lst[lf[x]].size()-qwq))-1;
}
}
ans[lf[x]]=ans[x];
mx[lf[x]]=mx[x];
return;
}
lst[x].push_back(1);
lf[x]=x;
ans[x]=0;
mx[x]=1;
flg[x]=1;
}
int main(){
int n;
cin>>n;
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
ve[u].push_back(v);
ve[v].push_back(u);
}
dfs(1,0);
for(int i=1;i<=n;i++)
if(flg[i])cout<<"0\n";
else cout<<ans[i]<<'\n';
return 0;
}
就是对于每个节点维护链表然后树上启发式合并链表
每次操作对于所有链的总长最多加
合并过程中每个点最多销毁一次
每次合并操作都会销毁一个点
时间复杂度 ,,?
求答疑 qwqwqwqwqwq
我不知道我没真正意义上学过启发式合并相关的东西 qwqwqwqwqwq
饭堂了补药喷窝 qwqwqwqwqwqwqwq
回复
共 8 条回复,欢迎继续交流。
正在加载回复...