Skip to content

Commit 2e87780

Browse files
committed
풀이: AtCoder Beginner Contest 448/D
?: DFS를 이용해 풀이
1 parent 72f8458 commit 2e87780

3 files changed

Lines changed: 176 additions & 0 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# D - Integer-duplicated Path
2+
3+
[링크](https://atcoder.jp/contests/abc448/tasks/abc448_d)
4+
5+
| 난이도 |
6+
| :----: |
7+
| 400 |
8+
9+
## 설계
10+
11+
### 시간 복잡도
12+
13+
그래프의 노드의 수를 V, 간선의 수를 E라 하자.
14+
15+
DFS를 이용해 1번 노드부터 그래프를 탐색하며 방문한 노드의 값들을 카운트해 중복된 값이 있는지 판단한다.
16+
17+
이 경우 DFS의 시간 복잡도는 O(V + E)이다.
18+
19+
### 공간 복잡도
20+
21+
그래프에 O(V + E), 방문 여부에 O(V), 값의 카운트에 O(V) 만큼의 공간이 필요하다.
22+
23+
### DFS
24+
25+
| 내 코드 (ms) | 시간 복잡도 | 공간 복잡도 |
26+
| :----------: | :---------: | :---------: |
27+
| 233 | O(V + E) | O(V + E) |
28+
29+
1번 노드부터 다른 모든 노드를 방문할 때 방분한 노드들의 값을 같이 저장한다.
30+
31+
1번부터 DFS로 탐색하며 각 노드마다 방문한 노드들의 값이 중복되는지 확인한다.
32+
33+
DFS로 노드를 방문 후 복귀할 때 방문한 노드의 값을 카운트에서 제거한다.
34+
35+
```cpp
36+
struct Edge {
37+
int from, to;
38+
};
39+
40+
vector<bool> solution(int size, vector<int>& nums, vector<Edge>& edges) {
41+
vector<bool> answer(size);
42+
43+
vector<vector<int>> graph(size + 1);
44+
for (Edge& e : edges) {
45+
graph[e.from].push_back(e.to);
46+
graph[e.to].push_back(e.from);
47+
}
48+
49+
unordered_set<int> visited;
50+
multiset<int> values;
51+
unordered_map<int, int> counts;
52+
53+
function<void(int, bool)> dfs = [&](int node, bool hasSame) {
54+
visited.insert(node);
55+
56+
int val = nums[node - 1];
57+
counts[val]++;
58+
59+
if (counts[val] >= 2) {
60+
hasSame |= true;
61+
}
62+
answer[node - 1] = hasSame;
63+
64+
for (int next : graph[node]) {
65+
if (visited.count(next)) continue;
66+
dfs(next, hasSame || counts[val] >= 2);
67+
}
68+
69+
counts[val]--;
70+
};
71+
72+
dfs(1, false);
73+
74+
return answer;
75+
}
76+
```
77+
78+
## 고생한 점
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#include <algorithm>
2+
#include <climits>
3+
#include <cmath>
4+
#include <cstring>
5+
#include <functional>
6+
#include <iostream>
7+
#include <map>
8+
#include <numeric>
9+
#include <queue>
10+
#include <set>
11+
#include <stack>
12+
#include <string>
13+
#include <unordered_map>
14+
#include <unordered_set>
15+
#include <vector>
16+
17+
using namespace std;
18+
19+
struct Edge {
20+
int from, to;
21+
};
22+
23+
vector<bool> solution(int size, vector<int>& nums, vector<Edge>& edges) {
24+
vector<bool> answer(size);
25+
26+
vector<vector<int>> graph(size + 1);
27+
for (Edge& e : edges) {
28+
graph[e.from].push_back(e.to);
29+
graph[e.to].push_back(e.from);
30+
}
31+
32+
unordered_set<int> visited;
33+
multiset<int> values;
34+
unordered_map<int, int> counts;
35+
36+
function<void(int, bool)> dfs = [&](int node, bool hasSame) {
37+
visited.insert(node);
38+
39+
int val = nums[node - 1];
40+
counts[val]++;
41+
42+
if (counts[val] >= 2) {
43+
hasSame |= true;
44+
}
45+
answer[node - 1] = hasSame;
46+
47+
for (int next : graph[node]) {
48+
if (visited.count(next)) continue;
49+
dfs(next, hasSame || counts[val] >= 2);
50+
}
51+
52+
counts[val]--;
53+
};
54+
55+
dfs(1, false);
56+
57+
return answer;
58+
}
59+
60+
int main() {
61+
ios_base ::sync_with_stdio(false);
62+
cin.tie(NULL);
63+
cout.tie(NULL);
64+
65+
cout.precision(10);
66+
67+
// freopen("./input.txt", "r", stdin);
68+
69+
int N;
70+
cin >> N;
71+
72+
vector<int> A(N);
73+
for (int i = 0; i < N; i++) {
74+
cin >> A[i];
75+
}
76+
77+
vector<Edge> edges(N - 1);
78+
for (int i = 0; i < N - 1; i++) {
79+
cin >> edges[i].from >> edges[i].to;
80+
}
81+
82+
auto answer = solution(N, A, edges);
83+
84+
// cout << answer << endl;
85+
for (bool line : answer) {
86+
cout << (line ? "Yes" : "No") << endl;
87+
// cout << line << "\n";
88+
}
89+
cout << endl;
90+
91+
return 0;
92+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
5
2+
1 3 2 1 2
3+
1 2
4+
1 3
5+
3 4
6+
3 5

0 commit comments

Comments
 (0)