CF 1805 D. A Wide, Wide Graph (*1800) 思维 + 树的直径
CF 1805 D. A Wide, Wide Graph (*1800) 思维 + 树的直径
题意:
思路:
若当前点到最远的点的距离
并且我们知道距离任意一点最远的点一定是树直径的一个端点。
反之,则与直径端点在同一个联通块。
所以一个点要么独立成为联通块,要么和直径端点在一个联通块。
代码:
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
void Showball(){
int n;
cin>>n;
vector<vector<int>> e(n);
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
u--;
v--;
e[u].push_back(v);
e[v].push_back(u);
}
vector<int> st(n),dis(n);
function<void(int)> dfs=[&](int u){
for(auto v:e[u]){
if(st[v]) continue;
st[v]=true;
dis[v]=dis[u]+1;
dfs(v);
}
};
st[0]=1;
dfs(0);
int maxn=0,S,E;
for(int i=0;i<n;i++){
if(dis[i]>maxn){
maxn=dis[i];
S=i;
}
dis[i]=st[i]=0;
}
st[S]=1;
dfs(S);
auto dis2=dis;
maxn=0;
for(int i=0;i<n;i++){
if(dis[i]>maxn){
maxn=dis[i];
E=i;
}
dis[i]=st[i]=0;
}
st[E]=1;
dfs(E);
vector<int> ans(n+1);
for(int i=0;i<n;i++){
if(i!=E) ans[max(dis[i],dis2[i])+1]++;
}
ans[0]=1;
for(int i=1;i<=n;i++) ans[i]+=ans[i-1];
for(int i=1;i<=n;i++) cout<<ans[i]<<" \n"[i==n];
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t=1;
//cin>>t;
while(t--){
Showball();
}
return 0;
}
分类:
算法竞赛
标签:
CF板刷(1600-1900)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】