Plite
전자오락 공방
Plite
전체 방문자
오늘
어제
  • 분류 전체보기 (274)
    • 프로젝트 (18)
      • 완성 프로젝트 (3)
      • 프로젝트 진행 내역 (15)
    • 공부 및 정리 (241)
      • 백준 코드 (222)
      • C++ (8)
      • DirectX (2)
      • Unreal Engine (6)
      • 프로그래밍 패턴 (3)
    • 기타 (12)
      • 기타 주저리 (10)
    • 게임과 취미 (1)
    • 대문 (1)

블로그 메뉴

  • 홈
  • 프로젝트
  • 취미, 일상
  • 백준 프로필

공지사항

  • [Read Me]
  • 제 블로그에 방문하신 것을 환영합니다.

인기 글

태그

  • 정렬
  • UC++
  • 수학
  • C++
  • 분할정복
  • 그래프
  • 누적합
  • 위상 정렬
  • 트라이
  • 스택
  • 기하
  • 트리
  • 백준
  • 구현
  • 이분탐색
  • LCA
  • 백트래킹
  • 정수론
  • 조합론
  • 유니온 파인드
  • 최소 스패닝 트리
  • SCC
  • 투포인터
  • 동적계획법
  • 큐
  • 문자열
  • KMP
  • 세그먼트 트리
  • 브루트포스
  • 우선순위큐

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Plite

전자오락 공방

[C++]백준 - 1949번 문제
공부 및 정리/백준 코드

[C++]백준 - 1949번 문제

2021. 11. 6. 16:43

1949번: 우수 마을 (acmicpc.net)

 

1949번: 우수 마을

N개의 마을로 이루어진 나라가 있다. 편의상 마을에는 1부터 N까지 번호가 붙어 있다고 하자. 이 나라는 트리(Tree) 구조로 이루어져 있다. 즉 마을과 마을 사이를 직접 잇는 N-1개의 길이 있으며,

www.acmicpc.net

 

1949번 : 우수 마을


N개의 마을로 이루어진 나라가 있다. 편의상 마을에는 1부터 N까지 번호가 붙어 있다고 하자. 이 나라는 트리(Tree) 구조로 이루어져 있다. 즉 마을과 마을 사이를 직접 잇는 N-1개의 길이 있으며, 각 길은 방향성이 없어서 A번 마을에서 B번 마을로 갈 수 있다면 B번 마을에서 A번 마을로 갈 수 있다. 또, 모든 마을은 연결되어 있다. 두 마을 사이에 직접 잇는 길이 있을 때, 두 마을이 인접해 있다고 한다.

이 나라의 주민들에게 성취감을 높여 주기 위해, 다음 세 가지 조건을 만족하면서 N개의 마을 중 몇 개의 마을을 '우수 마을'로 선정하려고 한다.

  1. '우수 마을'로 선정된 마을 주민 수의 총 합을 최대로 해야 한다.
  2. 마을 사이의 충돌을 방지하기 위해서, 만일 두 마을이 인접해 있으면 두 마을을 모두 '우수 마을'로 선정할 수는 없다. 즉 '우수 마을'끼리는 서로 인접해 있을 수 없다.
  3. 선정되지 못한 마을에 경각심을 불러일으키기 위해서, '우수 마을'로 선정되지 못한 마을은 적어도 하나의 '우수 마을'과는 인접해 있어야 한다.

각 마을 주민 수와 마을 사이의 길에 대한 정보가 주어졌을 때, 주어진 조건을 만족하도록 '우수 마을'을 선정하는 프로그램을 작성하시오.

 

입력


첫째 줄에 정수 N이 주어진다. (1 ≤ N ≤ 10,000) 둘째 줄에는 마을 주민 수를 나타내는 N개의 자연수가 빈칸을 사이에 두고 주어진다. 1번 마을부터 N번 마을까지 순서대로 주어지며, 주민 수는 10,000 이하이다. 셋째 줄부터 N-1개 줄에 걸쳐서 인접한 두 마을의 번호가 빈칸을 사이에 두고 주어진다.

 

 

출력


첫째 줄에 '우수 마을'의 주민 수의 총 합을 출력한다.

 


생각해 볼 점


2533번 문제와 유사하게 풉니다.

 

조건에 맞게

 

A가 우수마을이다. -> A의 child 마을들은 우수마을이 아니다.

A가 우수마을이 아니다 -> A의 Child 마을들은 우수마을 혹은 우수마을이 아니다.

 

의 경우로 풀어야합니다.

 

그런데, 문제에서 어떤 마을이 우수마을이 아니면

인접한 마을들 중 적어도 하나의 마을은 우수마을이어야 한다고 합니다.

 

그러면, A 마을이 우수마을이 아닐 때, 주위 마을 중 하나가 우수마을임을 검사해야할까요?

 

그렇지 않습니다.

 

 

A 마을이 다음과 같이 있고, A 마을이 만약 우수마을이 아니라 합시다.

 

그리고 A와 인접한 모든 마을들이 우수마을이 아닐 경우에

 

절대로 문제에서 요구하는 마을 주민들의 최대값을 구할 수 없습니다.

 

왜냐하면, A의 마을 주민의 수가 0이 아닌 이상에야 주변 마을이 모두 우수마을이 아니면

 

그냥 A를 우수마을로 선정하는 쪽이 최대값 구하기에 유리하기 때문입니다.

 

따라서 한 노드와 그 주변을 둘러싼 모든 마을이 우수마을이 아닌 경우는, 최대값을 구하고자 하는 입장에서

 

굳이 체크하지 않아도 절대로 존재할 수 없으니 3번 조건

 

선정되지 못한 마을에 경각심을 불러일으키기 위해서, '우수 마을'로 선정되지 못한 마을은 적어도 하나의 '우수 마을'과는 인접해 있어야 한다.

 

이건 그냥 무시해도 되는 조건입니다.

 

 

코드


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int** dp;
int* village;
bool* visited;
vector<int>* edge;

//DFS
void solution(int current)
{
	for(int next : edge[current])
	{
		if (visited[next]) continue;
		visited[next] = true;
		solution(next);
		dp[current][0] += max(dp[next][0], dp[next][1]);
		dp[current][1] += dp[next][0];
	}
	dp[current][1] += village[current];
}


int main()
{
	int N;
	scanf("%d", &N);

	dp = new int* [N];
	village = new int[N];
	visited = new bool[N];
	edge = new vector<int>[N];
	for (int i = 0; i < N; i++)
	{
		visited[i] = false;
		dp[i] = new int[2];
		dp[i][0] = 0;
		dp[i][1] = 0;
		scanf("%d", &village[i]);
	}


	for (int i = 0; i < N - 1; i++)
	{
		int a, b;
		scanf("%d %d", &a, &b);
		a--; b--;
		edge[a].push_back(b);
		edge[b].push_back(a);
	}
	visited[0] = true;
	solution(0);

	printf("%d", max(dp[0][0], dp[0][1]));	
	
	for (int i = 0; i < N; i++) delete[] dp[i];
	delete[] dp;
	delete[] visited;
	delete[] village;
	delete[] edge;
	return 0;
}

 

그 외


 

저작자표시 (새창열림)

'공부 및 정리 > 백준 코드' 카테고리의 다른 글

[C++]백준 - 1350번 문제  (0) 2021.11.11
[C++]백준 - 20149번 문제  (0) 2021.11.09
[C++]백준 - 2533번 문제  (0) 2021.11.06
[C++]백준 - 2213번 문제  (0) 2021.11.05
[C++]백준 - 1094번 문제  (0) 2021.11.05
    '공부 및 정리/백준 코드' 카테고리의 다른 글
    • [C++]백준 - 1350번 문제
    • [C++]백준 - 20149번 문제
    • [C++]백준 - 2533번 문제
    • [C++]백준 - 2213번 문제
    Plite
    Plite
    개발 일지, 게임 이야기 등을 적어두는 공간입니다.

    티스토리툴바