第一集光点構築ツリーは、ツリー状の直径を見つけます
const int型MAXN = 3E5 + 5。 const int型MAXM = 6E5 + 5。 const int型INF = 1E9; INTヘッド[MAXN]、[MAXM]、NEX [MAXM]、TOT。 ボイドインラインAddEdge(int型のx、int型のY){ 版【++ TOT = Y、NEX [TOT =頭部[X]頭[X] =死にました。 } 整数N、M。 BOOLブリッジ[MAXM]。 int型DFN [MAXN]、低[MAXN]。 int型NUM; ボイドTarjan(int型のx、int型のエッジ){ // coutの<< X <<てendl; [X] =低[X] = ++ NUM DFN。 {(; I I = NEX [I] INT iは[x]はヘッド=)用 yが版= INT [I]; IF(!DFN [Y]){ Tarjan(Y、I)。 低[X] =分(低[x]は、低[Y])。 IF(低[Y]> DFN [X]) ブリッジ[I] =ブリッジ[I ^ 1] = 1。 } それ以外の場合(I!=(エッジ^ 1)) 低[X] =分(低[x]は、DFN [Y])。 } } INT ID [MAXN]、BCC。 名前空間の解決{ INTヘッド[MAXN]、[MAXM]、NEX [MAXM]、TOT。 ボイドインラインAddEdge(int型のx、int型のY){ 版【++ TOT = Y、NEX [TOT =頭部[X]頭[X] =死にました。 } int型のF1 [MAXN]、F2 [MAXN]。 int型の年。 あなたは(あなたがPA、取得){DFS F1 [X] = F2 [X] = 0; {(; I I = NEX [I] INT iは[x]はヘッド=)用 yが版= INT [I]; if(y==pa) continue; dfs(y,x); if(f1[x]<f1[y]+1){ f2[x]=f1[x]; f1[x]=f1[y]+1; } else if(f2[x]<f1[y]+1){ f2[x]=f1[y]+1; } } ans=max(ans,f1[x]+f2[x]); return ans; } }; void dfs(int x,int pa){ id[x]=bcc; for(int i=head[x];i;i=nex[i]){ int y=ver[i]; if(y==pa || bridge[i] || id[y]) continue; dfs(y,pa); } } int main(){ scanf("%d%d",&n,&m); tot=1; for(int i=0;i<m;i++){ int x,y; scanf("%d%d",&x,&y); AddEdge(x,y); AddEdge(y,x); } for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i,0); // for(int i=1;i<=n;i++) // cout<<low[i]<<' '<<i<<endl; for(int i=1;i<=n;i++) if(!id[i]) bcc++,dfs(i,0); // cout<<bcc<<endl; // for(int i=1;i<=n;i++) // cout<<id[i]<<endl; for(int i=2;i<=tot;i+=2){ if(bridge[i]) { solve::AddEdge(id[ver[i]],id[ver[i^1]]); solve::AddEdge(id[ver[i^1]],id[ver[i]]); // cout<<id[ver[i]]<<' '<<id[ver[i^1]]<<endl; } } cout<<solve::dfs(1,0)<<endl; }