File tree Expand file tree Collapse file tree 1 file changed +62
-0
lines changed Expand file tree Collapse file tree 1 file changed +62
-0
lines changed Original file line number Diff line number Diff line change
1
+ /*
2
+ 풀이 :
3
+ graph가 tree가 되려면 모든 노드가 연결되어 있어야하고 순환이 없어야한다
4
+ 간선이 노드 개수 n - 1보다 작으면 모든 노드 연결 불가능, 크면 무조건 순환이 생긴다
5
+ 간선이 n - 1과 동일할 때 순환이 없으면 valid tree라고 판단 가능
6
+
7
+ Union-find 사용
8
+ - 시작할 때 각 노드는 자기 자신을 parent(root)로 가진다
9
+ - 노드가 서로 연결되있으면 한 union으로 합친 뒤 하나의 parent로 업데이트한다
10
+ - 이를 통해 한 parent를 가지는 한 그룹으로 묶이게 된다
11
+
12
+ find 함수는 한 그룹 전체의 parent를 재귀적으로 한 노드로 업데이트한다 (트리 깊이가 깊어져도 한번에 parent를 찾을 수 있게끔 경로최적화)
13
+
14
+ 두 노드의 find()결과 값이 같으면 이미 한 그룹에 속하는 것이므로 이 두 노드에 간선을 잇는 것은 순환이 생기는 것이다
15
+ 이를 통해 순환 있는지 판단
16
+
17
+ 노드 개수 : V, 간선 개수 : E
18
+ E = V - 1일 때만 유의미한 연산하므로 E ≈ V
19
+
20
+ TC : O(V)
21
+ 반복문 2회, find 함수의 재귀는 이론적으로 상수에 수렴한다고 한다
22
+
23
+ SC : O(V)
24
+ parent 배열
25
+ */
26
+
27
+ #include < vector>
28
+ #include < unordered_map>
29
+
30
+ using namespace std ;
31
+
32
+ class Solution {
33
+ public:
34
+ /* *
35
+ * @param n: An integer
36
+ * @param edges: a list of undirected edges
37
+ * @return: true if it's a valid tree, or false
38
+ */
39
+ vector<int > parent;
40
+ bool validTree (int n, vector<vector<int >> &edges) {
41
+ if (edges.size () != n - 1 )
42
+ return false ;
43
+
44
+ parent.resize (n);
45
+ for (int i = 0 ; i < n; i++)
46
+ parent[i] = i;
47
+
48
+ for (auto & edge : edges) {
49
+ int a = edge[0 ], b = edge[1 ];
50
+ int rootA = find (a), rootB = find (b);
51
+ if (rootA == rootB)
52
+ return false ;
53
+ parent[rootA] = rootB;
54
+ }
55
+ }
56
+
57
+ int find (int x) {
58
+ if (parent[x] != x)
59
+ parent[x] = find (parent[x]);
60
+ return parent[x];
61
+ }
62
+ };
You can’t perform that action at this time.
0 commit comments