-
Notifications
You must be signed in to change notification settings - Fork 0
2-sep037 #12
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| for _ in 0..<N-1 { | ||
| let edge = readLine()!.split(separator: " ").map {Int($0)!} | ||
|
|
||
| let a = edge[0] | ||
| let b = edge[1] | ||
|
|
||
| graph[a].append(b) | ||
| graph[b].append(a) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
전 중간에 변수 선언 없이 인덱스로 바로 넣어줬는데 마카로니씨처럼 선언해놓고 전달하는게 보기는 편한 것 같네요^^
전 아래처럼 짰슴다!
func getTree(_ n: Int) -> Tree {
var tree = Array(repeating: [Int](), count: n + 1)
for _ in 0..<n-1 {
let edge = readLine()!.split(separator: " ").map { Int($0)! }
// Tree = 양방향이라 양쪽 다연결해주기
tree[edge[0]].append(edge[1])
tree[edge[1]].append(edge[0])
}
return tree
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@MuchanKim 옹 트리생성도 모듈화하는거 좋네용 무!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
헉 우왕 주입식 교육 아주 좋습니다
쉬운 것부터 차근차근 . . ~
| func dfs(_ currentnode : Int){ | ||
| visited[currentnode] = true | ||
|
|
||
| for next in graph[currentnode] { | ||
| if !visited[next] { | ||
| parent[next] = currentnode | ||
| dfs(next) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| dfs(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
교과서적인 코드 잘 보고 갑니다. 저도 완전 똑같이 풀었습니다 ㅎㅎ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
기본에 충실하기 !
| let a = edge[0] | ||
| let b = edge[1] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이렇게도할 수 있고, 한줄로도 가능해요 !
취향차이긴한데, 공유합니다 !
let (a,b) = (edge[0],edge[1])There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
헉 ~ 아주 깔꼼스
앞으로 이렇게 쓰는 것도 습관화 해볼게요 !
감쟈합니다 🥹
| func dfs(_ currentnode : Int){ | ||
| visited[currentnode] = true | ||
|
|
||
| for next in graph[currentnode] { | ||
| if !visited[next] { | ||
| parent[next] = currentnode | ||
| dfs(next) | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
훨씬 깔끔하게 정석으로 푸셨네요.
괜히 막 처음에 복잡하게 생각하다보니까 다른쪽으로 풀었다가 돌아왔는데, 그래서 원래 복잡하게 풀어야하는지 알았어요.
전체코드는 코멘트로 달게요 !
bishoe01
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수도코드
edgeGraph: 간선그래프answerArr: 정답출력을 위한 각각 인덱스별 노드의 부모 저장소visited: contains로 판단하는 방문배열- BFS로 푸는데 지난번 킨더가든 선생님의 방식을 착안해서 이번에는 queue를 index로 관리해줘봤습니다.
queuePointer가 그 인덱스 관리 변수 Head에 관한 내용은 주석에 나온대로 만약 인덱스 1에 [4,6]이 들어있다면 이제 4,6을 살펴볼때 answerArr에 <너의 부모는 1이야>라고 등록을 해주려하는데, 타고올라가기가 번거로운것같아서 튜플로 바꾸고 속성에 head를 추가했습니다.
import Foundation
func solution(_ N: Int, _ graph: [[Int]]) {
var edgeGraph = Array(repeating: [Int](), count: N + 1)
var answerArr = Array(repeating: 0, count: N + 1)
var visited = Set<Int>()
for line in graph {
let (node1, node2) = (line[0], line[1])
edgeGraph[node1].append(node2)
edgeGraph[node2].append(node1)
}
var queue = [(head: 1, child: edgeGraph[1])] // 간선으로 놀아주는데, 만약 인덱스 1에 [4,6]이 들어있다면 이제 4,6을 살펴볼때 answerArr에 <너의 부모는 1이야>라고 등록을 해주려하는데, 타고올라가기가 번거로운것같아서 튜플로 바꾸고 속성에 head를 추가했어요
visited.insert(1)
var queuePointer = 0 // swift에서는 큐가 구현안되어있어서 pop,shift하는거 비효율적이니까 인덱스로 관리
// print(edgeGraph)
while queuePointer < queue.count {
for node in queue[queuePointer].child {
if !visited.contains(node) {
queue.append((head: node, child: edgeGraph[node]))
answerArr[node] = queue[queuePointer].head
visited.insert(node)
}
}
queuePointer += 1
}
// 출력 부분
for i in 2 ..< N + 1 {
print(answerArr[i])
}
}
giljihun
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/* MARK: - SOLUTION
<dfs풀이>
1. tree, parent, visited 배열 만들기
2. 입력
* 런타임에러 고려 - 숫자가 아닌 경우, 한 줄에 여러 숫자가 들어온 경우
3. dfs(1)부터 시작하여 방문노드 = true처리
4. 해당 노드에 연결된 간선을 하나씩 접근하여 종착역을 찾아서 업데이트
*/
import Foundation
guard let N = Int(readLine() ?? "") else { exit(0) }
var tree = Array(repeating: [Int](), count: N+1)
var parent = Array(repeating: 0, count: N+1)
var visited = Array(repeating: false, count: N+1)
for _ in 0..<N-1 {
guard let line = readLine() else { continue }
let parts = line.split(separator: " ").compactMap { Int($0) }
if parts.count == 2 {
let firstNode = parts[0], secondNode = parts[1]
tree[firstNode].append(secondNode)
tree[secondNode].append(firstNode)
} else { exit(0) }
}
func dfs(_ current: Int) {
visited[current] = true
for connectedNode in tree[current] {
if !visited[connectedNode] {
parent[connectedNode] = current
dfs(connectedNode)
}
}
}
dfs(1)
(2..<N+1).forEach { print(parent[$0]) }저는 이번 문제에선 런타임에러에 대한 PTSD로
조금 불필요할 수도 있는? 예외처리를 해주려고 노력했던거같아요
출력부분도 클로저로 깔끔하게 출력해봤습니다.
여러 리뷰를 하고 싶은데 입력부분, 출력문법 제외하면 그냥 똑같네요 ㅋㅋㅋ
- visited로 관리해주는건 무한 재귀에 빠질 수 있어서? 무조건 필수인 것 같아요.
- 그냥 문제마다 다르지 않나..? 싶은데 잘 모르겠습니다. 근데 크리티컬하진 않은 것 같아요 제 생각에!
| for i in 2...N { | ||
| print(parent[i]) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(2..<N+1).forEach { print(parent[$0]) }요런식으로 앞에 범위를 정해주고 .forEach로 한줄로 출력할 수도 있슴다~!!!
.forEach { ... } 는 배열이나 범위 안의 각 원소를 하나씩 꺼내서 중괄호 { } 안에 있는 코드를 실행!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이렇게 쓰면 멋쟁이가 되는 '길'이네요
꿀 팁 감 사 하 옵 니 다 ~ ~
YooGyeongMo
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dfs 문제 너무 좋았습니다 글로니. 코드가 엄청 깔끔하시군요.
| import Foundation | ||
|
|
||
| let N = Int(readLine()!)! | ||
|
|
||
| var graph = Array(repeating: [Int](), count: N+1) | ||
| var parent = Array(repeating:0, count: N+1) | ||
| var visited = Array(repeating: false, count: N+1) | ||
|
|
||
| for _ in 0..<N-1 { | ||
| let edge = readLine()!.split(separator: " ").map {Int($0)!} | ||
|
|
||
| let a = edge[0] | ||
| let b = edge[1] | ||
|
|
||
| graph[a].append(b) | ||
| graph[b].append(a) | ||
| } | ||
|
|
||
| func dfs(_ currentnode : Int){ | ||
| visited[currentnode] = true | ||
|
|
||
| for next in graph[currentnode] { | ||
| if !visited[next] { | ||
| parent[next] = currentnode | ||
| dfs(next) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| dfs(1) | ||
|
|
||
| for i in 2...N { | ||
| print(parent[i]) | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오 좋군요 !
이번에 문법 연습한다고 Array 확장해서 컴팩트 맵을 만들어보고
튜플로 받아보고자 한번 시도해봤는데 통과되더군요 다행입니다 호호..
tree[a].append(b)
tree[b].append(a)
하고싶어서 했더니 되더군요 !
함수를 좀 분리해서 사용해봤더니 좋은거같아요 호호
//
// 부모의 트리.swift
// 알고리즘 연습
//
// Created by Demian Yoo on 4/16/25.
//
/* TODO
1. 트리 구조 파악 -> 트리 루트 1, 양방향임
2. dfs 사용하면 될듯함 dfs(1)로 들어가서 깊이들어가서 빠져나오면서 그 위에 노드를 체크하고 뱉어주면됨.
3. 함수로 분할해보기
*/
import Foundation
let N = Int(readLine()!)!
var tree: [[Int]] = Array( repeating:[Int](), count: N+1 )
var parentArr: [Int] = Array( repeating:0, count: N+1 )
var visited = Array( repeating: false, count: N+1 )
// MARK - 함수 익스텐션 만들어보기
extension Array {
func makeMap<T>(_ transform: (Element) -> T?) -> [T] {
var result: [T] = []
for element in self {
if let value: T = transform(element) {
result.append(value)
}
}
return result
}
func asTuple() -> (Element, Element)? {
guard self.count == 2 else { return nil }
return (self[0], self[1])
}
}
// MARK - 트리 만들기
func makeTree(_ loop: Int) {
// loop-1번
for _ in 0..<loop {
// NOTE - 튜플로 들어감
if let (a, b) = readLine()!.split(separator: " ").makeMap({ Int($0) }).asTuple() {
tree[a].append(b)
tree[b].append(a)
}
}
}
// MARK - dfs 부모찾기
func findParentNode(_ idx: Int) {
visited[idx] = true
for nextIdx in tree[idx] {
if !visited[nextIdx] {
parentArr[nextIdx] = idx
findParentNode(nextIdx)
}
}
}
// MARK - 트리 출력하기
func printAnswer() {
// 1번 노드 루트라서 표현 X
for i in 2...N {
print(parentArr[i])
}
}
makeTree(N-1)
findParentNode(1)
printAnswer()
alstjr7437
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다들 이미 너무 완벽히 리뷰를 해주셨네요.. 할말이 없군요
코드도 다들 비슷한 것 같아서 저는 예전에 python으로 풀면서 bfs, dfs 연습했던거 참고했어요 ㅋㅋㅋ
import sys
sys.setrecursionlimit(10**8) #재귀 리미트
from collections import deque
n = int(input())
tree = {i:[] for i in range(1,n+1)}
for i in range(n-1):
a, b = map(int, input().split())
tree[a].append(b)
tree[b].append(a)
# print(tree)
visited = [0] * (n+1)
def dfs(a):
for i in tree[a]:
if visited[i] == 0:
visited[i] = a
# print(visited, i, a)
dfs(i)
def bfs():
while queue:
a = queue.popleft()
for i in tree[a]:
if visited[i] == 0:
queue.append(i)
visited[i] = a
# print(visited, queue)
visited[1] = '어무이'
# dfs(1)
queue = deque()
queue.append(1)
bfs()
for i in range(2, n+1):
print(visited[i])
🔗 문제 링크
트리의 부모 찾기
✔️ 소요된 시간
30분
✨ 수도 코드
문제를 살짝 요약해보자면
루트 없는 트리 -> 무방향 그래프 (간선 정보만 존재)
루트는 1로 지정
각 노드의 부모 노드 번호 출력 !
간선 정보를 바탕으로 인접 리스트를 생성하고
방문 기록을 담을 visited 배열과 부모 정보를 담을 배열을 선언했습니당
DFS 함수로 현재 연결된 노드 중
- 부모 노드 저장
- 재귀적으로 다음 노드 탐색
1번 루트 노드는 부모가 없으므로 제외하고 2번부터 N번 노드까지 부모를 출력했어요 !
📚 새롭게 알게된 내용
DFS는 재귀적으로 계속 깊이 들어가기 때문에 이미 방문한 노드에 방문 처리를 하는 습관을 꼭 들여야 겠다고 생각했어요
근데 제가 문제를 많이 안 풀어봐서 모르는데 노드는 거의 1부터 시작하나요 ? 여기서는 루트 노드가 1부터라 납득은 했는데 다른 문제들도 1부터인지 궁금해요 + 문제마다 다른지 .. ?