ABC428E

Solution

这题放第五题是真的简单了。
现在考虑四个点,$v,s,t,u$,这里 $v$ 是题目中的,$s,t$ 分别是树的直径的起点和终点,$u$ 是任意一点且 $u\neq s,u\neq t$。
分类讨论一下:

意思就是一定要先走到直径上再走到端点上,上面只是严格的证明。
记得选编号大的。

Code

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
int n,a,b,u1,u2;
int d[N],d1[N],d2[N];
vector<int> g[N];
queue<int> q;
void bfs(int s,int dis[]){
    memset(dis,-1,sizeof(d));
    dis[s]=0;
    while(!q.empty())q.pop();
    q.push(s);
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int v:g[u])if(dis[v]==-1)dis[v]=dis[u]+1,q.push(v);
    }
}
int main(){
    cin>>n;
    for(int i=1;i<n;i++){
        cin>>a>>b;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    bfs(1,d);
    u1=1;
    for(int i=2;i<=n;i++)if(d[i]>d[u1]||(d[i]==d[u1]&&i>u1))u1=i;
    bfs(u1,d1);
    u2=u1;
    for(int i=1;i<=n;i++)if(d1[i]>d1[u2]||(d1[i]==d1[u2]&&i>u2))u2=i;
    bfs(u2,d2);
    for(int i=1;i<=n;i++){
        if(d1[i]>d2[i])cout<<u1<<"\n";
        else if(d1[i]<d2[i])cout<<u2<<"\n";
        else cout<<max(u1,u2)<<"\n";
    }
    return 0;
}