[BOJ/20924] 트리의 기둥과 가지, c++

2021. 3. 29. 14:26·DEV/PS

www.acmicpc.net/problem/20924

 

20924번: 트리의 기둥과 가지

첫 번째 줄에는 노드의 개수 $N$($1 \le N \le 200\,000$)과 루트 노드의 번호 $R$($1 \le R \le N$)이 주어진다. 이후 $N-1$개의 줄에 세 개의 정수 $a$, $b$, $d$($1 \le a, b \le N$, $ a \ne b$)가 주어진다. 이는 $a$번

www.acmicpc.net

한줄 후기: 코드가 너무 더러운 것 같다..

 

//AC
//BOJ 20924 트리의 기둥과 가지

#include <iostream>
#include <vector>
using namespace std;
vector<pair<int, int> > v[200001];
int visit[200001];
int gi = 0, gidoong, ans = 0;
void dfs(int node, int pa, int R){
	visit[node] = 1;
	if(v[node].size() == 2){
		if(node == R){
			gidoong = node;
			return;
		}
		else{
			if(v[node][0].first != pa){
				gi += v[node][0].second;
				dfs(v[node][0].first, node, R);
			}
			else{
				gi += v[node][1].second;
				dfs(v[node][1].first, node, R);
			}
		}
	}
	else if(v[node].size() > 2){
		gidoong = node;
	}
	else if(v[node].size() == 1){
		if(node == R){
			gi += v[node][0].second;
			dfs(v[node][0].first, node, R);
		}
		else gidoong = node;
	}	
	return;
}
void maxCost(int node, int pa, int cur){
	visit[node] = 1;
	if(v[node].size() == 1){
		ans = max(ans, cur);
		return;
	}
	for(int i=0; i<v[node].size(); i++){
		pair<int, int> next = v[node][i];
		if(next.first == pa)	continue;
		if(!visit[next.first]){
			cur += next.second;
			maxCost(next.first, node, cur);
			cur -= next.second;
		}
	}
	
}
int main(){
	ios_base :: sync_with_stdio(false); 
	cin.tie(NULL); 
	cout.tie(NULL);
	int N, R;
	cin >> N >> R;
	for(int i=0; i<N-1; i++){
		int a, b, d;
		cin >> a >> b >> d;
		v[a].push_back({b, d});
		v[b].push_back({a, d});
	}
	if(N == 1){
		cout << gi << " " << gidoong;
		return 0;
	}
	dfs(R, 0, R);
	maxCost(gidoong, gidoong, 0);
	cout << gi << " " << ans;
	return 0;
}

기가노드를 먼저 구했다.

기가노드는 dfs 느낌으로 재귀를 통해 구하는데 만약 벡터에 자식이 3개 이상 있다면 (하나는 자식이 아니라 부모) 그 노드가 바로 기가노드가 된다.

2개 일때는 조건을 나눠야 하는데 만약 현재 노드가 루트라면 부모가 없으므로 2개라는건 바로 자식이 2개란 것

따라서 바로 기가노드가 된다.

그게 아니라면 cost를 더해주면서 재귀를 돌린다. 

만약 벡터에 연결된 노드가 한개 밖에 없다면, 현재 노드가 루트일 경우 재귀 , 아닐 경우 그 노드가 리프노드임으로 기가노드가 된다.

 

그 후, maxCost 함수를 통해 가장 긴 가지의 길이를 구한다. 

자식 노드들에게 재귀를 돌리는데 재귀를 돌고 나오면 다시 부모로 돌아오는 거니 cur에서 cost를 빼줘야 한다.

리프노드에 도착하면 현재 가지의 길이와 이전 max가지 길이와 비교해 더 큰 값을 저장해둔다.

 

 

 

저작자표시 비영리 변경금지 (새창열림)

'DEV > PS' 카테고리의 다른 글

[BOJ/20922] 겹치는 건 싫어, c++  (0) 2021.04.05
[BOJ/14938] 서강 그라운드, c++  (0) 2021.04.05
[BOJ/9466] 텀 프로젝트, c++  (0) 2021.03.16
[BOJ/20955] 민서의 응급 수술, c++  (0) 2021.03.08
[BOJ/20956] 아이스크림 도둑 지호, c++  (0) 2021.03.08
'DEV/PS' 카테고리의 다른 글
  • [BOJ/20922] 겹치는 건 싫어, c++
  • [BOJ/14938] 서강 그라운드, c++
  • [BOJ/9466] 텀 프로젝트, c++
  • [BOJ/20955] 민서의 응급 수술, c++
jobchae
jobchae
말하는 감자지만, 코드를 끄적이는 Node.js 백엔드 개발자입니다.
  • jobchae
    JOBCHAE
    jobchae
  • 전체
    오늘
    어제
    • 🚀 JOBCHAE (177)
      • DEV (146)
        • PS (108)
        • Node.js (12)
        • React (3)
        • docker (1)
        • 잡다한 개발 일지 (20)
        • injection (1)
        • CI CD (0)
        • JS, TS (1)
      • 축구 (0)
      • 일상 (19)
      • 영화 (3)
      • 음악 (8)
  • 블로그 메뉴

    • 💻 Github
    • 🙋🏻 Linkedin
    • 📖 방명록
  • 링크

    • PS Github
  • 공지사항

  • 인기 글

  • 태그

    slack
    react
    렛츠락페스티벌
    node.js
    슬랙
    백준
    aws
    nodejs
    boj
    솝트
    일상
    회고
    DFS
    DP
    리액트
    SOPT
    PS
    위상정렬
    mongoDB
    Nest.js
    슬랙봇
    BFS
    typescript
    이분탐색
    GitHub
    Nest
    Express
    앱잼
    알고리즘
    우선순위큐
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
jobchae
[BOJ/20924] 트리의 기둥과 가지, c++
상단으로

티스토리툴바