cf1000E

 

 第一集光点構築ツリーは、ツリー状の直径を見つけます

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;
}

  

おすすめ

転載: www.cnblogs.com/033000-/p/12323013.html