Loading [MathJax]/jax/output/HTML-CSS/jax.js

المپدیا

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

ابزار کاربر

ابزار سایت


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

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

در این قسمت نیز به مانند یال برشی مقدار 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;
}

ابزار صفحه