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