빠른 입출력을 한 번 적용해보세요
1967번 - 트리의 지름
언어마다 속도가 현저히 다르고, 서로 빠르고 느린 부분이 다르며, 비슷한 로직이라도 실제로 어떤 연산들로 이루어져있느냐에 따라 큰 차이가 발생하는 것은 당연합니다. 파이썬은 이를 감안해서 다른 언어에 비해 훨씬 많은 시간 보너스를 제공하고 있습니다. 그럼에도 불구하고 파이썬이 다소 불리한 것은 사실입니다.
질문에 올려주신 코드는 시간 복잡도가 O(N^2)입니다. 이는 N의 제한이 최대 1만인 것과, 상수가 다소 크다는 점, 그리고 문제가 매우 오래됐다는 점을 감안하면 그다지 2초 내에 통과되기를 바라는 풀이가 아니라고 보입니다. 그럼에도 불구하고 요즘 컴퓨터가 너무 빨라져서 대다수의 언어에서 이런 풀이가 통과될 수 있을 뿐입니다. 설령 같은 풀이로 통과되지 않는 언어가 있다고 해도 문제의 시간 제한이 잘못되었다고 볼 수는 없습니다.
이 문제에는 O(N)의 풀이가 있습니다. 그런 풀이를 작성하신다면 파이썬으로도 아주 넉넉하게 통과될 수 있습니다.
댓글을 작성하려면 로그인해야 합니다.
coms1101 2년 전
정말 파이썬이 이렇게 느린 언어인가요...?
파이썬코드로는 통과되지 않았던 알고리즘이 코틀린으로 제출하니 풀리네요....
언어 마다 속도가 다르다지만 이런 알고리즘에서 같은 알고리즘인데 어떤 언어는 통과되고 어떤 언어는 통과가 안된다는게 조금 이해할 수가 없네요...
ps.
코틀린은 클래스에 맴버변수로 선언했고 파이썬은 그냥 함수의 매개변수로 전달해서 거기에서 속도차이가 날 수 있다라고 하실 수도 있어서 말하자면 파이썬에서도 클래스를 구현해서 맴버변수로 만들어서 제출해봤습니다. 정말 코틀린으로 작성한 코드와 언어의 유형만 다르다고 할 정도로 똑같이....
하지만 파이썬에서는 시간초과로 통과가 안되더라구요.....ㅠㅠㅠㅠ
이게 백준 사이트에서의 최적화 문제인 건가요...?
여러 언어로 문제를 풀 수 있다는 점은 좋지만 같은 알고리즘인데 언어가 다르다고 결과가 다른 점은 조금 아쉽네요.....
class Tree(var n: Int) {
private var graph: ArrayList<ArrayList<ArrayList<Int>>> = ArrayList<ArrayList<ArrayList<Int>>>()
private var visited: ArrayList<Boolean> = ArrayList<Boolean>()
private var leafNode: ArrayList<Int> = ArrayList<Int>()
init {
for(i in 0..this.n) {
this.graph.add(ArrayList<ArrayList<Int>>())
this.visited.add(false)
}
makeTree()
}
// 트리 만들기
private fun makeTree() {
for(i in 1 until this.n) {
var nodeWeight = readLine()!!.split(" ").map{ it.toInt() }
// 부모노드에 (자식노드, 가중치) 저장
var edge = arrayListOf(nodeWeight[1], nodeWeight[2])
this.graph[nodeWeight[0]].add(edge)
// 자식노드에 (부모노드, 가중치) 저장
edge = arrayListOf(nodeWeight[0], nodeWeight[2])
this.graph[nodeWeight[1]].add(edge)
}
// leafNode 만들기
for(i in 1..this.n) {
if(this.graph[i].size == 1) {
this.leafNode.add(i)
}
}
}
// 노드의 가장 먼 노드까지의 길이 구하기
private fun lineLength(node: ArrayList<Int>): Int {
// 현재 노드 방문 처리
this.visited[node[0]] = true
var length = 0
// 깊이 우선 탐색
for (i in this.graph[node[0]]) {
if(!this.visited[i[0]]) {
var tmp = i[1] + lineLength(i)
// 현재 구해진 길이보다 길다면 tmp 값으로 변경
length = if(length < tmp) tmp else length
}
}
return length
}
// 결과 구하기
fun getAnswer() {
var answer = 0
for(idx in this.leafNode) {
// 방문 처리 리스트
for(i in 0..this.n) {
this.visited[i] = false
}
// 시작노드 방문 처리
this.visited[idx] = true
// 시작노드에 연결된 노드 방향으로 길이 구하기
var length = graph[idx][0][1] + lineLength(graph[idx][0])
// 이전 길이보다 길경우 answer 값 변경
answer = if(answer < length) length else answer
}
println(answer)
}
}
fun main() {
var n: Int = readLine()!!.toInt()
var tree = Tree(n)
tree.getAnswer()
}