[백준] 11266번 단절점 (C++)
문제Permalink
그래프가 주어졌을 때, 단절점을 모두 구하는 프로그램을 작성하시오. 단절점이란 그 정점을 제거했을 때, 그래프가 두 개 이상으로 나누어지는 정점을 말한다.
입력Permalink
첫째 줄에 두 정수 V(1≤V≤10,000), E(1≤E≤100,000)가 주어진다.
다음 E개의 줄에는 간선 정보를 나타내는 두 정수 A, B가 주어진다.
이는 A번 정점과 B번 정점이 연결되어 있다는 뜻이다.
예제 입력 1Permalink
7 7
1 4
4 5
5 1
1 6
6 7
2 7
3 7
출력Permalink
첫째 줄에 단절점의 개수를 출력한다. 둘째 줄에는 단절점의 번호를 공백으로 구분해 오름차순으로 출력한다.
예제 출력 1Permalink
3
1 6 7
풀이Permalink
문제 해결 방법Permalink
이 문제는 DFS를 사용하여 그래프의 단절점을 찾는 문제입니다. 단절점을 찾기 위한 주요 단계는 다음과 같습니다:
- DFS 순회: 그래프를 DFS로 순회하면서 각 정점의 방문 순서를 기록합니다.
- Low Link Value: 각 정점에서 도달할 수 있는 가장 일찍 방문한 정점의 번호를 계산합니다.
- 단절점 판별:
- 루트 노드: 자식이 2개 이상이면 단절점
- 그 외 노드: 자식 노드들 중 하나라도 자신보다 낮은 정점으로 가지 못하면 단절점
이 알고리즘의 시간 복잡도는 O(V + E)입니다.
코드Permalink
#include<vector>
#include<stdio.h>
#include<algorithm>
using namespace std;
int n,m;
vector<int> mp[10001];
int dist[10001],dd;
int cut[10001];
int dfs(int node,bool r)
{
dist[node]=++dd;
int rtn = dd;
int child=0;
for(int p : mp[node])
{
if(dist[p]==0)
{
child++;
int child_low = dfs(p,0);
if(!r&&child_low>=dist[node])
{
cut[node]=1;
}
rtn = min(rtn,child_low);
}
else
rtn = min(rtn,dist[p]);
}
if(r&&child>1)
{
cut[node]=1;
}
return rtn;
}
int main()
{
int i,j,x,y;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
mp[x].push_back(y);
mp[y].push_back(x);
}
for(i=1;i<=n;i++)
if(dist[i]==0)
dfs(i,true);
int ans = 0;
for(i=1;i<=n;i++)
{
ans+=cut[i];
}
printf("%d\n",ans);
for(i=1;i<=n;i++){
if(cut[i])printf("%d ",i);
}
return 0;
}
댓글남기기