본문 바로가기
programming/알고리즘

[백준, G4, 1043] 거짓말

by s2econd.blue 2022. 10. 29.

0. 문제 링크

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

 

1043번: 거짓말

지민이는 파티에 가서 이야기 하는 것을 좋아한다. 파티에 갈 때마다, 지민이는 지민이가 가장 좋아하는 이야기를 한다. 지민이는 그 이야기를 말할 때, 있는 그대로 진실로 말하거나 엄청나게

www.acmicpc.net


1. 문제 핵심

  1. 지민이는 거짓말쟁이로 알려지기는 싫어한다. 
  2. 문제는 몇몇 사람들은 그 이야기의 진실을 안다는 것이다. 따라서 이런 사람들이 파티에 왔을 때는, 지민이는 진실을 이야기할 수 밖에 없다. 
  3. 당연히, 어떤 사람이 어떤 파티에서는 진실을 듣고, 또다른 파티에서는 과장된 이야기를 들었을 때도 지민이는 거짓말쟁이로 알려지게 된다. 지민이는 이런 일을 모두 피해야 한다.
  4. 지민이는 모든 파티에 참가해야 한다. 이때, 지민이가 거짓말쟁이로 알려지지 않으면서, 과장된 이야기를 할 수 있는 파티 개수의 최댓값을 구하는 프로그램을 작성하시오.

2. 문제 접근

  1. 각 사람 별 속한 파티를 Map에 저장, 각 파티에 별 속한 사람을 Map에 저장해서 진실을 말하는 사람을 Queue에 저장해서 속한 파티를 방문 체크해주고 같이 파티에 속한 사람들도 계속 Queue에 넣어 체크해주었습니다.

3. 코드 분석

  1.  

4. 베스트 코드 분석

  1.  

5. 코드

더보기
import java.util.*;
import java.io.*;

public class Main {
	// 정답: 파티 최대 개수를 출력

	// 1. 우선 진실을 아는 사람들이 있는 파티에선 거짓말 불가
	// 2. 진실을 아는 사람들과 함께 있던 사람들은 파티에서 거짓말 불가
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());

		int people = Integer.parseInt(st.nextToken());
		int party = Integer.parseInt(st.nextToken());

		st = new StringTokenizer(br.readLine());
		int truth = Integer.parseInt(st.nextToken());

		// 해당 사람이 진실을 말하는 사람인지 저장
		boolean[] truthArr = new boolean[people + 1];
		// 진실을 말하는 사람의 번호를 저장
		int[] truths = new int[people + 1];
		// 진실을 아는 사람들을 저장
		Queue<Integer> q = new LinkedList<>();
		// 진실을 아는 사람들을 구분
		// 파티별 방문 처리 및 거짓말 가능 표시 배열
		// 0: 미방문, 1: 방문했지만 진실을 아는 사람 없음, 2: 방문했고 진실을 아는 사람들 존재
		int[] visit = new int[party];
		int known;
		for (int i = 0; i < truth; i++) {
			known = Integer.parseInt(st.nextToken());
			truthArr[known] = true;
			truths[i] = known;
			q.add(known);
		}

		int players;
		// 사람별 참석 파티 저장
		Map<Integer, List<Integer>> peopleToParty = new HashMap<>();

		// 파티 별 사람의 수 출력
		Map<Integer, List<Integer>> partyToPeople = new HashMap<>();
		int eachPeople;

		for (int i = 0; i < party; i++) {
			st = new StringTokenizer(br.readLine());
			players = Integer.parseInt(st.nextToken());

			List<Integer> partyPeople = new LinkedList<>();
			for (int j = 0; j < players; j++) {
				// 파티별 참석자를 입력
				eachPeople = Integer.parseInt(st.nextToken());
				// 각 파티에 참석한 사람의 명단 출력
				partyPeople.add(eachPeople);

				// 각 사람별 참석 파티 리스트를 호출
				if (peopleToParty.containsKey(eachPeople)) {
					List<Integer> tmp = peopleToParty.get(eachPeople);
					tmp.add(i);
					peopleToParty.put(eachPeople, tmp);
				}
				// Hash에 해당 사람이 저장되어있지 않을 때
				else {
					List<Integer> tmp = new ArrayList<>();
					tmp.add(i);
					peopleToParty.put(eachPeople, tmp);
				}
			}
			// 각 파티에 참석하는 사람의 목록을 저장
			partyToPeople.put(i, partyPeople);
		}

		while (!q.isEmpty()) {
			// 진실을 아는 사람
			known = q.poll();

			// 진실을 아는 사람들이 속한 파티 순회
			if (peopleToParty.get(known) == null)
				continue;

			for (int i : peopleToParty.get(known)) {
				if (visit[i] == 0) {
					visit[i] = 2;
					for (int j : partyToPeople.get(i)) {
						q.add(j);
					}
				}
			}
		}
		int answer = 0;
		for (int i = 0; i < party; i++) {
			if (visit[i] == 0) {
				answer++;
			}
		}
		System.out.println(answer);
	}
}

'programming > 알고리즘' 카테고리의 다른 글

[백준, G3, 8972] 미친 아두이노  (0) 2022.12.21
뉴스 정하기  (0) 2022.10.30
[백준, G3, 2539] 모자이크  (0) 2022.10.23
[백준, 15486, G5] 퇴사 2  (0) 2022.10.20
[백준, 14719, G5] 빗물  (0) 2022.10.20

댓글