도넛 모양 그래프, 막대 모양 그래프, 8자 모양 그래프들이 있습니다. 이그래프들은 1개이상의정점과, 정점들을연결하는단방향간선으로이루어져있습니다.
크기가 n인 도넛 모양 그래프는 n개의 정점과 n개의 간선이 있습니다. 도넛 모양 그래프의 아무 한 정점에서 출발해 이용한 적 없는 간선을 계속 따라가면 나머지 n-1개의 정점들을 한 번씩 방문한 뒤 원래 출발했던 정점으로 돌아오게 됩니다.
도넛 모양 그래프 형태 예시
크기가 n인 막대 모양 그래프는 n개의 정점과 n-1개의 간선이 있습니다. 막대 모양 그래프는 임의의 한 정점에서 출발해 간선을 계속 따라가면 나머지 n-1개의 정점을 한 번씩 방문하게 되는 정점이 단 하나 존재합니다.
막대 모양 그래프의 형태 예시
크기가 n인 8자 모양 그래프는 2n+1개의 정점과 2n+2개의 간선이 있습니다. 8자 모양 그래프는 크기가 동일한 2개의 도넛 모양 그래프에서 정점을 하나씩 골라 결합시킨 형태의 그래프입니다.
8자 모양 그래프 예시
도넛 모양 그래프, 막대 모양 그래프, 8자 모양 그래프가 여러 개 있습니다. 이 그래프들과 무관한 정점을 하나 생성한 뒤, 각 도넛 모양 그래프, 막대 모양 그래프, 8자 모양 그래프의 임의의 정점 하나로 향하는 간선들을 연결했습니다. 그 후 각 정점에 서로 다른 번호를 매겼습니다.
이때 당신은 그래프의 간선 정보가 주어지면 생성한 정점의 번호와 정점을 생성하기 전 도넛 모양 그래프의 수, 막대 모양 그래프의 수, 8자 모양 그래프의 수를 구해야 합니다.
그래프의간선정보를담은 2차원정수배열 edges가매개변수로주어집니다. 이때, 생성한정점의번호, 도넛모양그래프의수, 막대모양그래프의수, 8자모양그래프의수를순서대로 1차원정수배열에담아 return 하도록 solution 함수를완성해주세요.
생성 노드의 out 간선은 총 모양 그래프의 개수이다. (무관 정점에서 해당 모양으로 가는 그래프로 가는 정점으로 연결)
도넛 모양 그래프
무관 정점에서 이어진 노드를 제외한 모든 노드가 in 간선 1개, out 간선 1개
막대 모양 그래프
보통 노드가 in 간선 1개, out 간선 1개
막대그래프의 끝 노드는 in 간선 1개, out 간선 0개
8 자 모양 그래프
보통 노드가 in 간선 1개, out 간선 1개
중심 노드는 in 간선 2개, out 간선 2개
그래프 별 특징
in 간선 (노드로 들어오는 간선)
out 간선 (노드에서 나가는 간선)
무관 정점 (생성 노드)
0
2 이상
도넛 모양 그래프 (모든 노드)
1
1
막대 모양 그래프 (마지막 노드)
1
0
8자 모양 그래프 (중심 노드)
2
2
모든 간선정보를 in, out으로 나눠서 저장한다.
out 간선이 2 이상이고 in 간선이 없으면 생성노드
out 간선이 2개, in 간선이 2개이면 8자 모양 중심 노드
in 간선 1개, out 간선이 없으면 막대모양 마지막 노드
도넛 모양 그래프 개수는 총 그래프 개수 - (막대 + 8 자) 개수
코드
import java.util.HashMap;
import java.util.Map;
public class P_258711 {
private static int[] solution(int[][] edges) {
// in, out 간선 정보 저장
Map<Integer, Integer> out = new HashMap<>();
Map<Integer, Integer> in = new HashMap<>();
int[] answer = new int[4];
// 노드 별로 in, out 간선 정보 저장
for(int[] edge : edges) {
out.put(edge[0], out.getOrDefault(edge[0], 0) + 1);
in.put(edge[1], out.getOrDefault(edge[1], 0) + 1);
}
// 총 그래프 개수 (생성 노드의 out 개수가 우리가 찾는 그래프 개수)
int total = 0;
// 처음 for 문에서 생성노드와 8자 모양 개수를 파악
for (int node : out.keySet()) {
// out 차수가 2개 이상이라면 생성 노드 혹은 8자 모양 중심 노드이다.
if(out.get(node)>=2) {
// 진출 차수가 있으면 8자 모양 중심 노드
if (in.containsKey(node)) {
answer[3] += 1;
} else {
// 진출 차수가 없으면 시작 노드
answer[0] = node;
total = out.get(node);
}
}
}
// in 간선맵에서 in 간선 개수가 1이고 out 간선이 없는 노드는 직선 그래프의 마지막 노드
for (int node : in.keySet()) {
if (in.get(node)==1 && !out.containsKey(node)) {
answer[2] += 1;
}
}
// 도넛 그래프 개수 = 총 그래프 - (막대 + 8자 모양)
answer[1] = total - (answer[2] + answer[3]);
return answer;
}
}