알고리즘문제

백준 1167(트리의 지름)

연구자H 2021. 1. 30. 02:02

 

https://www.acmicpc.net/problem/1967

 

1967번: 트리의 지름

파일의 첫 번째 줄은 노드의 개수 n(1 ≤ n ≤ 10,000)이다. 둘째 줄부터 n-1개의 줄에 각 간선에 대한 정보가 들어온다. 간선에 대한 정보는 세 개의 정수로 이루어져 있다. 첫 번째 정수는 간선이 연

www.acmicpc.net

트리의 지름이란, 트리에서 임의의 두 점 사이의 거리 중 가장 긴 것을 말한다.

 

처음에는 모든 노드에 대해서 루트로 잡은 노드와 가장 먼 노드와의 길이를 dfs를 통해 구해보았다. 

당연하게도 시간초과가 발생하였다.

 

한번의 DFS 로 풀 수 있는 방법이 있을까 고민해보았다.

 

생각의 흐름.

 

1. 내가 현재 루트로 잡은 노드가 트리의 지름에 포함되어있는 경우

-> 이 경우 루트 노드부터 한 리프 노드까지가 트리의 지름일 수 도 있고, 아니면 한 리프 노드부터 루트 노드를 지나 다른 리프 노드까지가 지름일 수 있다.

 

2. 내가 현재 루트로 잡은 노드가 트리의 지름에 포함되어있지 않을 경우

그림이 허접하지만 빨간색 노드가 루트 노드이고 파란 부분이 트리의 지름이다.

위 그림같은 경우를 말할 수 있다.

 

여기까지 생각해보니  하나의 노드에서 두가지를 처리해주면 위에서 정리한 두가지 경우를 모두 처리할 수 있을 것 같았다.

 

첫번째, 자식 노드는 부모에게 자신부터 리프노드까지의 길이 중 최대값을 반환해준다.

두번째, 부모 노드는 자식 노드들 중에서 가장 긴 두개의 노드 길이의 합을 구해 answer와 비교한다.

 

위의 설명으로 알아들을 사람은 없을 것 같다.. 설명을 더 잘할 수 있도록 노력해야겠다.

#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
vector<pair<int,int>>vec[100001];

bool check[100001];

int ans = 0;
int dfs(int now){
    int first=0;
    int second =0;
    for(int i=0; i<vec[now].size(); i++){
        if(check[vec[now][i].first] ==false){
            check[vec[now][i].first]=true;
            int temp = dfs(vec[now][i].first) + vec[now][i].second;
            if(first < temp || second < temp ){
                if(first <= second)first = temp;
                else second = temp;
            }
        }
        
    }
    if(ans < first + second)ans =first + second;
    return max(first,second);
}

int main(){
    int n;
    scanf("%d",&n);
    
    int st,fi,score;
    for(int i=0; i<n; i++){
        scanf("%d",&st);
        while(1){
            scanf("%d",&fi);
            if(fi != -1){
                scanf("%d",&score);
                vec[st].push_back(make_pair(fi,score));
            }
            else break;
        }
    }
    check[1] = true;
    dfs(1);
    printf("%d",ans);
    
    return 0;
}

근데 왜 DFS 한번 쓴 내 풀이가 기존 풀이보다 속도가 느린것일까..

대부분 80ms 에서 끝내는데 내 코드는 108ms 걸린다...

 

문제를 푼 뒤 다른 풀이를 찾아보니 DFS 두번 적용하여 푸는 방법도 있었다.

설명으로 보나  코드로 보나 내 풀이보다 깔끔한 것 같다.

 

'알고리즘문제' 카테고리의 다른 글

백준 14003(가장 긴 증가하는 부분 수열 5)  (0) 2021.02.16