link
题意:
求树上三个点之间的最长距离,每条边被覆盖了只算一次贡献。
思路:
求树的直径,然后再找一个点到树直径上节点距离最大。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=200010;
vector<int>v[N];
int n;
int mxdep;
int resa,resb;
vector<int>seq;
bool flag=0;
set<int>s;
void dfs(int u,int dep,int fa,int &res,bool ff)
{
if(dep>mxdep)
{
mxdep=dep;
res=u;
}
for(auto j:v[u])
{
if(j==fa) continue;
if(ff)
seq.push_back(j);
if(ff && j==resb&&!flag)
{
flag=1;
for(auto x:seq)
{
// cout<<x<<endl;
s.insert(x);
}
}
dfs(j,dep+1,u,res,ff);
if(ff && seq.size())
seq.pop_back();
}
}
int ans;
void dfss(int u,int dep,int fa)
{
if(dep>=mxdep)
mxdep=max(mxdep,dep),ans=u;
for(auto j:v[u])
{
if(!s.count(j) && j!=fa)
dfss(j,dep+1,u);
}
}
int main()
{
cin>>n;
for(int i=0;i<n-1;i++)
{
int a,b;
cin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
dfs(1,0,-1,resa,0);
mxdep=0;
seq.push_back(resa);
dfs(resa,0,-1,resb,0);
int tmp=mxdep;
dfs(resa,0,-1,resb,1);
mxdep=0;
for(auto x:s)
{
if(x!=resa && x!=resb)
{
//cout<<x<<endl;
dfss(x,0,-1);
}
}
tmp+=mxdep;
cout<<tmp<<endl;
cout<<resa<<" "<<resb<<" "<<ans<<endl;
return 0;
}