🎯 목표 : 주어진 무 방향 그래프의 간선 목록을 가지고 인접 행렬을 구현하고 DFS 탐색 방식으로 Component의 갯수를 찾는 알고리즘 작성.
public class FindComponent {
private int max=0;
private int [][] adj;
private int [] collect;
private int value = 0;
private int count = 0; // 컴포넌트 갯수 카운트
public int countComponent(int[][] edges) {
for (int[] edge : edges) {
if (edge[0] > max) {
max = edge[0];
}
if (edge[1] > max) {
max = edge[1];
}
}
adj = new int[max+1][max+1];
collect = new int[max+1];
for (int[] ints : adj) { // 행렬과 배열에 모든 값을 0으로 초기화
Arrays.fill(collect,0);
Arrays.fill(ints, 0);
}
for (int[] i : edges) { // 인자로 받은 간선 목록을 가지고 행렬에 추가
adj[i[0]][i[1]] = 1;
adj[i[1]][i[0]] = 1;
}
findComponent(); // 컴포넌트 갯수 카운터 호출
return count;
}
// 행렬을 받아 두 정점이 이어져 있는지 확인
private boolean isLinked(int[][] adj,int from, int to){
return adj[from][to]==1&&adj[to][from]==1;
}
// DFS 순회
private void dfsRecur(int v){
/* vertex 만큼의 길이를 가진 배열을
* 하나하나 방문할때 체크 하며 count와 동일한 value를 배열에 넣어준다
* 각 vertex 마다 몇번째 Component에 속하는지 표시*/
collect[v] = value;
// vertex 갯수 만큼 순회
for(int i=0; i<collect.length; i++){
// 두 정점이 이어져있고, vertex에 방문한적이 없다면 재귀 호출
// 정점이 이어져있지 않다면, 다음 요소 까지 재귀호출을 하지 않는다.
// 재귀 호출을 하지 않았다는건,
// i의 해당 요소가 매개 변수에 해당하는 vertex와 연결되어 있지 않았거나,
// i에 해당하는 vertex에 방문한적이 있기 때문.
if(isLinked(adj,v,i)&&collect[i]==0){
dfsRecur(i);
}
}
}
// Vertex 별로 순회 해줌
private void findComponent(){
count = 0;
Arrays.fill(collect,0); // 배열 초기화
for(int i =0; i<collect.length; i++){
// 해당 vertex에 방문한적이 없다면
if(collect[i]==0){
value++;
dfsRecur(i);
count++;
}
}
}
}