Skip to content

Commit f6a9cb9

Browse files
authored
Merge pull request #1040 from AlgorithmWithGod/0224LJH
[20251004] PRO / LV2 / 도넛과 막대 그래프 / 이종환
2 parents f7352a9 + b66fb4d commit f6a9cb9

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
```java
2+
import java.io.*;
3+
import java.util.*;
4+
5+
class Solution {
6+
7+
// 결국 자신으로 향하는 노드가 없는 경우는 딱 두가지임
8+
// 1. 막대 그래프에서의 시작점
9+
// 2. 추가된 간선
10+
// 하지만 둘간의 차이점 존재. 1번은 내가 가리키는 노드가 반드시 1개, 2번은 최소 2개 이상
11+
// 이를 통해서, 몇번을 추가했는지 찾은 후, 걔를 빼고 나머지 간선들로 계산하면됨
12+
// 이때 1번들을 기억해놓고, 얘네들이 곧 막대 모양 그래프 개수임
13+
// 나머지는 bfs 진행하면 된다.
14+
// bfs 진행하면서 만약 내가 가리키고 있거나, 가리킴 당하는게 2개 이상이면 8자, 한번도 그런적 없으면 도넛.
15+
16+
static final int TO = 1;
17+
static final int FROM = 0;
18+
static final int NEW_NODE = 0;
19+
20+
static boolean[] visited = new boolean[1000_001];
21+
static int[] answer = new int[4];
22+
static Node[] nodes = new Node[1000_001];
23+
static ArrayList<Integer> stickStart =new ArrayList<>();
24+
25+
static int newNode;
26+
27+
static class Node{
28+
int num;
29+
int parentCnt = 0;
30+
List<Node> to = new ArrayList<>();
31+
public Node(int num){
32+
this.num = num;
33+
}
34+
}
35+
36+
public int[] solution(int[][] edges) {
37+
findAndRemoveNewNode(edges);
38+
makeNode(edges);
39+
makeAns();
40+
return answer;
41+
}
42+
43+
private void makeAns(){
44+
for (int i = 1; i <= 1000_000; i++){
45+
if (visited[i]) continue;
46+
if (nodes[i].parentCnt == 0) stickStart.add(i);
47+
}
48+
49+
for (int t: stickStart){
50+
bfs(t,true);
51+
}
52+
53+
for (int i = 1; i <= 1000_000; i++){
54+
if (visited[i]) continue;
55+
bfs(i,false);
56+
}
57+
}
58+
59+
private void bfs(int target,boolean isStick){
60+
Node node = nodes[target];
61+
visited[target] = true;
62+
int maxToCnt = 0;
63+
64+
Queue<Node> q = new LinkedList<>();
65+
q.add(node);
66+
67+
while(!q.isEmpty()){
68+
Node n = q.poll();
69+
maxToCnt = Math.max(maxToCnt, n.to.size());
70+
for (Node t: n.to){
71+
if( visited[t.num]) continue;
72+
visited[t.num] = true;
73+
q.add(t);
74+
}
75+
}
76+
77+
if (isStick){
78+
answer[2]++;
79+
return;
80+
}
81+
82+
if (maxToCnt > 1) answer[3]++;
83+
else answer[1]++;
84+
}
85+
86+
private void makeNode(int[][] edges){
87+
for (int i = 1; i <= 1000_000; i++){
88+
if (visited[i]) continue;
89+
nodes[i] = new Node(i);
90+
}
91+
92+
93+
for (int i = 0; i < edges.length; i++){
94+
int fromNum = edges[i][FROM];
95+
int toNum = edges[i][TO];
96+
97+
if (fromNum == newNode || toNum == newNode) continue;
98+
99+
nodes[fromNum].to.add(nodes[toNum]);
100+
nodes[toNum].parentCnt++;
101+
}
102+
103+
}
104+
105+
private void findAndRemoveNewNode(int[][] edges){
106+
int[][] arr = new int[2][1000_001];
107+
108+
for (int i = 0; i < edges.length; i++){
109+
int fromNum = edges[i][FROM];
110+
int toNum = edges[i][TO];
111+
112+
arr[TO][toNum]++;
113+
arr[FROM][fromNum]++;
114+
}
115+
116+
for (int i = 0; i <= 1000_000; i++){
117+
if( arr[TO][i] == 0 && arr[FROM][i] == 0){
118+
visited[i] = true;
119+
continue;
120+
}
121+
122+
if (arr[TO][i] == 0 ){
123+
if (arr[FROM][i] > 1){
124+
answer[NEW_NODE] = i;
125+
newNode = i;
126+
visited[i] = true;
127+
continue;
128+
}
129+
130+
}
131+
132+
133+
}
134+
135+
}
136+
}
137+
```

0 commit comments

Comments
 (0)