المپدیا

دانش‌نامه‌ی المپیاد کامپیوتر ایران

ابزار کاربر

ابزار سایت


آموزش:الگوریتم‌های تکمیلی:پیدا کردن راس برشی

پیدا کردن راس برشی

در این قسمت نیز به مانند یال برشی مقدار $dp[i]$ را با همان تعریف برای راس $i$ به دست می آوریم. حال یک راس برشی است اگر وقتی آن را جدا می کنیم گراف به بیش از یک مولفه تقسیم شود در نتیجه در درخت $DFS$ که ساختیم به ازای راس $v$ اگر مقدار $dp$ یکی از فرزندانش بیشتر مساوی مقدار ارتفاع راس $v$ بود یعنی یالی به بالای آن نداشت ، آنگاه این راس برشی خواهد بود. برای راس ریشه نیز حالت خاصی در نظر می گیریم که اگر درجه آن در درخت $DFS$ بیشتر از یک بود آنگاه برشی است.

زمان اجرای این الگوریتم $O(n+m)$ است. ( $n$ نشان دهنده تعداد راس ها و $m$ نشان دهنده تعداد یال ها است.)

پیاده سازی این الگوریتم را در کد زیر مشاهده می کنید.

#include<iostream>
#include<vector>
 
using namespace std;
 
const int maxn=1000000+10;
 
bool mark[maxn],is[maxn];
int dp[maxn],h[maxn];
vector<int> adj[maxn];
 
void dfs(int v,int parent){
	dp[v]=h[v];
	mark[v]=true;
	int num=0;
	for(int i=0;i<adj[v].size();i++){
		int u=adj[v][i];
		if(!mark[u]){
			h[u]=h[v]+1;
			dfs(u,v);
			if(v!=1 && dp[u]>=h[v])is[v]=true;
			dp[v]=min(dp[v],dp[u]);
			num++;
		}
		else{
			if(u!=parent){
				dp[v]=min(dp[v],h[u]);
			}
		}
	}
	if(v==1 && num>1){
		is[v]=true;
	}
	return;
}
 
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=0;i<m;i++){
		int u,v;
		cin>>u>>v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++){
		if(is[i]){
			cout<<i<<" ";	
		}
	}
	return 0;
}

ابزار صفحه