Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[최단 경로] 2176063 김서현 #353

Open
wants to merge 22 commits into
base: 2176063-김서현2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5c5694a
[5월 19일] 트리 라이브 코딩 코드 업로드
jk0527 May 19, 2023
cf31227
Merge branch 'main' of https://github.com/Altu-Bitu-Official/Altu-Bitu-4
jk0527 May 19, 2023
a8cc122
[5월 19일] 트리 리드미 수정
jk0527 May 19, 2023
5ab3590
[5월 23일] 트리 과제 코드 업로드
jk0527 May 23, 2023
20be664
Merge branch 'main' of https://github.com/Altu-Bitu-Official/Altu-Bitu-4
jk0527 May 23, 2023
dad8d2c
[5월 23일] 트리 리드미 수정
jk0527 May 23, 2023
1373cde
[5월 23일] 최단 경로 강의 자료 업로드
jk0527 May 23, 2023
6d1de48
Merge branch 'main' of https://github.com/Altu-Bitu-Official/Altu-Bitu-4
jk0527 May 23, 2023
b57dc56
[5월 23일] 최단 경로 리드미 업로드
jk0527 May 23, 2023
c908c33
[5월 23일] 리드미 수정
jk0527 May 23, 2023
dfb69e0
[5월 26일] 최단 경로 강의 자료 수정
jk0527 May 26, 2023
65bd5df
[5월 26일] 최단 경로 강의 자료 수정
jk0527 May 26, 2023
7b46298
[5월 26일] 최단 경로 라이브 코딩 코드 업로드
jk0527 May 26, 2023
74a7044
Merge branch 'main' of https://github.com/Altu-Bitu-Official/Altu-Bitu-4
jk0527 May 26, 2023
fce223d
[5월 26일] 최단 경로 리드미 수정
jk0527 May 26, 2023
91e590f
[최단 경로] 0530
sforseohn May 30, 2023
c36add7
Merge branch '2176063-김서현2' into 13-assignment
sforseohn May 30, 2023
0efc874
[최단 경로] 0530
sforseohn May 30, 2023
020306f
Merge branch '13-assignment' of https://github.com/sforseohn/Altu-Bit…
sforseohn May 30, 2023
042e028
[최단 경로] 0602
sforseohn Jun 2, 2023
5cedeff
[최단 경로] 추가제출
sforseohn Jun 2, 2023
0e0ea97
Merge branch '2176063-김서현2' into 13-assignment
sforseohn Jun 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions 12_트리/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@

| 문제 번호 | 문제 이름 | 난이도 | 풀이 링크 | 분류 |
| :-----------------------------------------------------------------------: | :----------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------: | :----------: | :--------: |
| <a href="https://www.acmicpc.net/problem/1991" target="_blank">1991</a> | <a href="https://www.acmicpc.net/problem/1991" target="_blank">트리 순회</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/10.svg"/> | [바로가기]() | 트리 순회 |
| <a href="https://www.acmicpc.net/problem/4803" target="_blank">4803</a> | <a href="https://www.acmicpc.net/problem/4803" target="_blank">트리</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/12.svg"/> | [바로가기]() | 트리, DFS |
| <a href="https://www.acmicpc.net/problem/1991" target="_blank">1991</a> | <a href="https://www.acmicpc.net/problem/1991" target="_blank">트리 순회</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/10.svg"/> | [바로가기](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/12_%ED%8A%B8%EB%A6%AC/%EB%9D%BC%EC%9D%B4%EB%B8%8C%20%EC%BD%94%EB%94%A9/1991.cpp) | 트리 순회 |
| <a href="https://www.acmicpc.net/problem/4803" target="_blank">4803</a> | <a href="https://www.acmicpc.net/problem/4803" target="_blank">트리</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/12.svg"/> | [바로가기](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/12_%ED%8A%B8%EB%A6%AC/%EB%9D%BC%EC%9D%B4%EB%B8%8C%20%EC%BD%94%EB%94%A9/4803.cpp) | 트리, DFS |

## ✏️ 과제

Expand All @@ -22,16 +22,16 @@

| 문제 번호 | 문제 이름 | 난이도 | 풀이 링크 | 분류 |
| :-----------------------------------------------------------------------: | :------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------: | :-------: | :------------------------: |
| <a href="https://www.acmicpc.net/problem/3190" target="_blank">3190</a> | <a href="https://www.acmicpc.net/problem/3190" target="_blank">뱀</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/11.svg"/> | [C++]() | 구현, 시뮬레이션, 자료구조 |
| <a href="https://www.acmicpc.net/problem/15681" target="_blank">15681</a> | <a href="https://www.acmicpc.net/problem/15681" target="_blank">트리와 쿼리</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/11.svg"/> | [C++]() | 트리, 그래프 탐색, DP |
| <a href="https://www.acmicpc.net/problem/5639" target="_blank">5639</a> | <a href="https://www.acmicpc.net/problem/5639" target="_blank">이진 검색 트리</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/11.svg"/> | [C++]() | 트리, 그래프 탐색 |
| <a href="https://www.acmicpc.net/problem/3190" target="_blank">3190</a> | <a href="https://www.acmicpc.net/problem/3190" target="_blank">뱀</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/11.svg"/> | [C++](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/12_%ED%8A%B8%EB%A6%AC/%ED%95%84%EC%88%98/3190.cpp) | 구현, 시뮬레이션, 자료구조 |
| <a href="https://www.acmicpc.net/problem/15681" target="_blank">15681</a> | <a href="https://www.acmicpc.net/problem/15681" target="_blank">트리와 쿼리</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/11.svg"/> | [C++](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/12_%ED%8A%B8%EB%A6%AC/%ED%95%84%EC%88%98/15681.cpp) | 트리, 그래프 탐색, DP |
| <a href="https://www.acmicpc.net/problem/5639" target="_blank">5639</a> | <a href="https://www.acmicpc.net/problem/5639" target="_blank">이진 검색 트리</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/11.svg"/> | [C++](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/12_%ED%8A%B8%EB%A6%AC/%ED%95%84%EC%88%98/5639.cpp) | 트리, 그래프 탐색 |

### 도전

| 문제 번호 | 문제 이름 | 난이도 | 풀이 링크 | 분류 |
| :--------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------: | :-------: | :--: |
| <a href="https://www.acmicpc.net/problem/1967" target="_blank">1967</a> | <a href="https://www.acmicpc.net/problem/1967" target="_blank">트리의 지름</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/12.svg"/> | [C++]() | 트리, 그래프 탐색 |
| <a href="https://www.acmicpc.net/problem/24545" target="_blank">24545</a> | <a href="https://www.acmicpc.net/problem/24545" target="_blank">Y</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/16.svg"/> | [C++]() | 트리 그래프 탐색, DP |
| <a href="https://www.acmicpc.net/problem/1967" target="_blank">1967</a> | <a href="https://www.acmicpc.net/problem/1967" target="_blank">트리의 지름</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/12.svg"/> | [C++](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/12_%ED%8A%B8%EB%A6%AC/%EB%8F%84%EC%A0%84/1967.cpp) | 트리, 그래프 탐색 |
| <a href="https://www.acmicpc.net/problem/24545" target="_blank">24545</a> | <a href="https://www.acmicpc.net/problem/24545" target="_blank">Y</a> | <img height="25px" width="25px" src="https://static.solved.ac/tier_small/16.svg"/> | [C++](https://github.com/Altu-Bitu-Official/Altu-Bitu-4/blob/main/12_%ED%8A%B8%EB%A6%AC/%EB%8F%84%EC%A0%84/24545.cpp) | 트리 그래프 탐색, DP |
---

### 힌트
Expand Down
71 changes: 71 additions & 0 deletions 12_트리/도전/1967.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include<iostream>
#include<vector>

using namespace std;
typedef pair<int, int> ci;

/* weight가 더해지면서 탐색의 depth가 늘어나고 최종적으로 node와 가중치가 return된다
* return 될 때 cur 노드의 자식 노드 중에서 weight가 가장 큰 노드로 갱신
* 결국 root 에서 가장 먼 노드 번호와 weigth가 return됨!!
*/
ci dfs(int cur, int prev, vector<vector<ci>>& graph, int weight) {
int max_node = cur;
int max_edge = weight;

for (int i = 0; i < graph[cur].size(); i++) {

int next_node = graph[cur][i].first;
int next_edge = graph[cur][i].second;

if (next_node == prev) {
continue;
}

ci search = dfs(next_node, cur, graph, weight+next_edge); // 자식 노드에 대해서 dfs 탐섹

if (search.second > max_edge) { // 자식 노드의 return 값 중 큰 걸로 갱신됨
max_node = search.first;
max_edge = search.second;
}
}
return { max_node, max_edge };
}

/**
* Hint : 지름을 이루는 노드의 특징은 무엇일까요?
* [트리의 지름]
*
* 1. 지름을 이루는 두 점은 모두 리프 노드
* 2. 임의의 한 노드에서 가장 멀리 있는 노드(리프 노드)는 지름을 이루는 노드 중 하나
* 3. 지름을 이루는 노드에서 가장 멀리 있는 노드는 지름을 이루는 다른 노드
*
* 부모->자식의 방향만 저장하면 리프 노드에서 다른 리프 노드로 탐색할 수 없으므로 무방향 그래프로 저장
*/



int main() {
// 입력
int n;
cin >> n;
vector<vector<ci>> graph(n + 1, vector<ci>(0));
int v1, v2, e;
for (int i = 0; i < n - 1; i++) {
cin >> v1 >> v2 >> e;
graph[v1].push_back({ v2,e });
graph[v2].push_back({ v1,e });
}

// 연산

// 1. 루트에서 가장 먼 노드 찾기
ci farmost = dfs(1, -1, graph, 0);

// 2. 1에서 찾은 노드에서 가장 먼 노드 찾기
ci another_farmost = dfs(farmost.first, -1, graph, 0);

// 출력
cout << another_farmost.second;

return 0;
}
69 changes: 69 additions & 0 deletions 12_트리/도전/24545.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* HINT : 사용할 수 있는 정점의 종류를 고려해서 트리의 모양을 추측해보세요!
*
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>

using namespace std;

int dfs(int curr, int prev, vector<vector<int>>& tree, vector<map<int, int>>& cnt_node) {
if (cnt_node[prev][curr]) { // 이미 저장해둔 값 있으면 바로 리턴
return cnt_node[prev][curr];
}
int cnt = 0;

for (int next : tree[curr]) {
if (next == prev) { // 직전에 방문한 노드는 돌아가지 않음 -> 만약 이부분이 없다면? 무한루프
continue;
}
cnt = max(cnt, dfs(next, curr, tree, cnt_node)); // 최댓값 갱신
}
//cout << prev << " -> " << curr << ' ' << cnt + 1 << '\n'; // 디버깅용
return cnt_node[prev][curr] = cnt + 1;
}

int getMaxYTree(int n, vector<vector<int>>& tree, vector<map<int, int>>& cnt_node) {
int ans = 0;

// Y-트리의 중심이 될 노드를 순차적으로 탐색
for (int curr = 1; curr <= n; curr++) {
if (tree[curr].size() < 3) { // 간선의 수 < 3인 경우 중심이 될 수 없음
continue;
}
vector<int> cnt; // 해당노드(curr)에서 나오는 간선에서 얻을 수 있는 노드의 수 저장

for (int next : tree[curr]) {
cnt.push_back(dfs(next, curr, tree, cnt_node));
}
sort(cnt.begin(), cnt.end(), greater<>());
ans = max(ans, cnt[0] + cnt[1] + cnt[2] + 1); // 가장 많은 노드를 선택할 수 있는 경우 세가지 + 중심점(curr)
}

return ans;
}

int main() {
int n, u, w;
vector<vector<int>> tree; // 인접리스트 형태로 저장
vector<map<int, int>> cnt_node; // 간선에 노드 수 저장

// 입력
cin >> n;

// 입력 + 초기화
tree.assign(n + 1, vector<int>(0));
cnt_node.assign(n + 1, map<int, int>());

for (int i = 0; i < n - 1; i++) {
cin >> u >> w;
tree[u].push_back(w);
tree[w].push_back(u);
}

// 연산 + 출력
cout << getMaxYTree(n, tree, cnt_node);
return 0;
}
Empty file.
58 changes: 58 additions & 0 deletions 12_트리/라이브 코딩/1991.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <iostream>
#include <map>

using namespace std;

map<char, pair<char, char>> tree;

// 전위 순회는 V - L - R
void preorder(char v) {
if (v == '.') {
return;
}
cout << v;
preorder(tree[v].first);
preorder(tree[v].second);
}

// 중위 순회 L - V - R
void inorder(char v) {
if (v == '.') {
return;
}

inorder(tree[v].first);
cout << v;
inorder(tree[v].second);
}

// 후위 순회 L - R - V
void postorder(char v) {
if (v == '.') {
return;
}

postorder(tree[v].first);
postorder(tree[v].second);
cout << v;
}

int main() {
int n;
char root, left, right;

// 입력
cin >> n;
while (n--) {
cin >> root >> left >> right;
tree[root] = { left, right };
}

// 연산 + 출력
preorder('A');
cout << '\n';
inorder('A');
cout << '\n';
postorder('A');
return 0;
}
87 changes: 87 additions & 0 deletions 12_트리/라이브 코딩/4803.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include<iostream>
#include<vector>

using namespace std;

// 결과 출력 함수
void printResult(int tc, int cnt) {
cout << "Case " << tc << ": ";

switch (cnt) {
case 0:
cout << "No trees.\n";
break;
case 1:
cout << "There is one tree.\n";
break;
default:
cout << "A forest of " << cnt << " trees.\n";
}
return;
}

void dfs(bool& flag, int cur, int prev, vector<vector<int>>& graph, vector<bool>& visited) {

if (visited[cur]) { // 방문했던 곳을 또 방문했다면 트리가 아니다
flag = false;
return;
}

visited[cur] = true; // 방문 체크

for (int next : graph[cur]) {
if (next == prev) {
continue;
}
dfs(flag, next, cur, graph, visited);
}
return ;
}

/*
* 각 그래프가 트리인지 아닌지 판단
* 사이클이 생기면 트리 아님
* 사이클이 생긴다 -> DFS로 자기 자신으로 돌아올 수 있다.
*/

int main() {
int n, m, t, v1, v2;

for (t = 1;;t++) { // 테스트 케이스 번호

// 입력
cin >> n >> m;

if (!n && !m) { // 종료 조건
break;
}

// 그래프 입력
vector<vector<int>> graph(n+1, vector<int>(0));
for (int i = 0; i < m; i++) {
cin >> v1 >> v2;
graph[v1].push_back(v2);
graph[v2].push_back(v1);
}

int cnt = 0; // 트리 수 카운트
vector<bool> visited(n + 1, false); // 방문 표시

for (int i = 1; i <= n; i++) {
if (visited[i]) {
continue;
}

bool flag = true; // 트리인지 여부 저장하는 변수
dfs(flag, i, 0, graph, visited);
if (flag) {
cnt++;
}

}

// 출력
printResult(t, cnt);
}
return 0;
}
Empty file.
57 changes: 57 additions & 0 deletions 12_트리/필수/15681.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include<iostream>
#include<vector>
#include<map>

using namespace std;

/*
* 트리의 정점의 수 구하기 응용 문제
*
* 1. 루트에서 DFS를 사용하여 탐색
* 2. 각 노드를 루트로 하는 서브트리의 정점 수를 재귀적으로 벡터에 저장
* - 서브트리에 속한 정점의 개수를 저장하는 dp 배열을 1로 초기화
* - 탐색 시 현재 정점의 자식 노드만 탐색해서 현재 정점의 dp 값에 더해줌
* 3. 쿼리로 주어지는 정점의 서브트리의 정점의 개수를 dp에서 찾아서 출력
*/

void dfs(int cur, int prev, vector<vector<int>>& tree, vector<int>& dp) {

for (int i = 0; i < tree[cur].size(); i++) { // 현재 정점의 자식 노드 탐색
if (tree[cur][i] == prev) {
continue;
}
dfs(tree[cur][i], cur,tree, dp);
dp[cur] += dp[tree[cur][i]]; // 자식 노드의 dp값 더해주기
}

return;
}

int main() {

ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);

// 입력
int n, r, q, u, v;
cin >> n >> r >> q;

vector<vector<int>>tree(n + 1, vector<int>(0));

for (int i = 0; i < n - 1; i++) {
cin >> u >> v;
tree[u].push_back(v);
tree[v].push_back(u);
}

// 연산
vector<int>dp(n + 1, 1); // 자신도 자신을 루트로 하는 서브트리에 포함되므로 0이 아닌 1로 dp 초기값 설정
dfs(r, 0,tree, dp);

// 출력
while (q--) {
cin >> u;
cout <<dp[u] << '\n';
}
}
Loading