5
2 3
1 4
4 5
3 5
3 4
6
2 6
3 4
1 5
5 6
4 6
4 5
두 경우 모두 진입차수가 0인 경우는 없으며, 진입차수가 1인 경우를 제거했을 때 정답을 구할 수 있는 경우입니다. 그림으로 그려보면 이해하기 쉽습니다.
진입차수가 1인 경우를 포함하면 순환참조 문제가 발생합니다.
// 처음 생각한 위상정렬 코드, 단순히 0값을 판단하던 곳을 0또는 1을 판단하게(<2)로 바꿔줬습니다.
for (int i = 1; i <= N; i++) {
if(inDegree[i] < 2) {
pq.add(i);
}
}
while(!pq.isEmpty()) {
int now = pq.poll();
if(v[now]) continue;
v[now] = true;
for (int targetVal : graph.get(now)) {
inDegree[targetVal]--;
if(inDegree[targetVal] < 2) {
pq.add(targetVal);
}
}
}
진입차수를 0인 경우만 고려했을 때는 a->b->c->a
의 경우가 pq에 들어오지 못했습니다.
하지만 진입차수가 1인 경우를 포함하면 위 경우가 pq에 들어오고 이때 무한루프에 빠질 수 있습니다.
[1,1,1]
입니다. 여기서 a
를 pq에 넣었다고 가정해 봅시다.a
가 나왔습니다. a
는 자신과 연결된 b
의 진입차수를 1 줄입니다. b
는 진입차수가 0이 되어 pq에 들어갑니다.b
가 나왔습니다. b
는 자신과 연결된 c
의 진입차수를 1 줄입니다. c
는 진입차수가 0이 되어 pq에 들어갑니다.c
가 나왔습니다. c
는 자신과 연결된 a
의 진입차수를 1 줄입니다. a
는 진입차수가 0이 되어 pq에 들어갑니다.a
가 나왔습니다. a
는 자신과 연결된 b
의 진입차수를 1 줄입니다. 음수의 진입차수를 가질 수 없게 막아두더라도 b의 진입차수는 2보다 작은 값이 되어 또다시 pq
에 들어갑니다.
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
HashMap<Integer,int[]> graph = new HashMap<Integer,int[]>();
int[] inDegree = new int[N+1];
boolean[] v = new boolean[N+1];
for (int i = 1; i <= N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
inDegree[a]++;
inDegree[b]++;
graph.put(i, new int[] {a,b});
}
PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
for (int i = 1; i <= N; i++) {
if(inDegree[i] < 2) {
pq.add(i);
}
}
while(!pq.isEmpty()) {
int now = pq.poll();
if(v[now]) continue;
v[now] = true;
for (int targetVal : graph.get(now)) {
inDegree[targetVal]--;
if(inDegree[targetVal] < 2) {
pq.add(targetVal);
}
}
}
StringBuilder sb = new StringBuilder();
int cnt = 0;
for (int i = 1; i <= N; i++) {
if(inDegree[i] == 2) {
cnt++;
sb.append(i+" ");
}
}
System.out.println(cnt);
System.out.println(sb.toString());
}
}