1부터 N까지 정수 N개로 이루어진 순열을 나타내는 방법은 여러 가지가 있다. 예를 들어, 8개의 수로 이루어진 순열 (3, 2, 7, 8, 1, 4, 5, 6)을 배열을 이용해 표현하면 (1234567832781456) 와 같다. 또는, Figure 1과 같이 방향 그래프로 나타낼 수도 있다.
순열을 배열을 이용해 (1…i…nπ1…πi…πn) 로 나타냈다면, i에서 πi로 간선을 이어 그래프로 만들 수 있다.
Figure 1에 나와있는 것 처럼, 순열 그래프 (3, 2, 7, 8, 1, 4, 5, 6) 에는 총 3개의 사이클이 있다. 이러한 사이클을 "순열 사이클" 이라고 한다.
N개의 정수로 이루어진 순열이 주어졌을 때, 순열 사이클의 개수를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스의 첫째 줄에는 순열의 크기 N (2 ≤ N ≤ 1,000)이 주어진다. 둘째 줄에는 순열이 주어지며, 각 정수는 공백으로 구분되어 있다.
출력
각 테스트 케이스마다, 입력으로 주어진 순열에 존재하는 순열 사이클의 개수를 출력한다.
사이클이라는 것이 결국 사이클을 이루는 노드 전체를 하나의 노드로 생각하고 카운트 하면 된다. 따라서 visit배열을 만들고 처음 들어오는 인덱스에 대해서 방문 하지 않았다면 우선 카운트를 하나 올리고 DFS로 보내서 이 인덱스가 가르키는 다음 노드 들에 대해 꼬리를 물고 전부 방문 표시를 해버린다. 그렇게 되면 인덱스가 올라가서 그 위치의 인덱스가 되어도 같은 사이클의 인덱스이므로 이미 방문 표시가 되있어서 카운트를 세지 않게 된다.
#include <iostream>
using namespace std;
int arr[1001];
int N;
bool visit[1001];
void DFS(int node)
{
visit[node]=true;
if(!visit[arr[node]])
DFS(arr[node]);
}
int main(void)
{
cin >>N;
int amount;
for(int i=0; i<N; i++)
{
for(int j=1; j<1001; j++)
visit[j]=false;
cin >> amount;
for(int j=1; j<=amount; j++)
{
cin >> arr[j];
}
int cnt =0;
for(int j=1; j<=amount; j++)
if(!visit[j])
{
DFS(j);
cnt++;
}
cout << cnt <<endl;
}
}
'Algorithm' 카테고리의 다른 글
백준 2026번 바이러스 (0) | 2019.07.23 |
---|---|
백준 1927번 최소힙 (0) | 2019.07.23 |
백준 1032번 명령프롬프트 (0) | 2019.07.21 |
백준 10808번 알파벳 개수 (0) | 2019.07.21 |
백준 11004번 K번째 수 (0) | 2019.07.20 |