본문 바로가기
algorithm/boj

백준 1043 거짓말

by 권성호 2021. 10. 2.

1. 문제 링크

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

 

1043번: 거짓말

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

www.acmicpc.net

 

2.  풀이

 

문제의 핵심은 

진실을 알고 있는 사람이 참석한 파티를 모두 제거하는 것 

 

파티에 대한 참석자 배열과 참석자에 대한 파티 배열 2개를 만든 후 BFS방식을 통해 진실을 알고 있는 사람이 참석한 모든 파티를 제거할 수 있다. 간단한 알고리즘은 아래와 같다.

 

  1. 최초에 진실을 알고있는 사람을 모두 queue에 push 
  2. qeueue가 비워질 때까지
    1.  queue에서 원소 하나 pop(진실을 알고 있는 사람) 
    2.  진실을 알고 있는 사람이 참석한 모든 파티에 대해(참석자에 대한 파티 배열을 통해 조회), 아직 거짓 파티로 표시된 경우 => 진실의 파티로 표시
    3.  1에서 진실의 파티로 표시된 파티에 참석한 모든 사람들에 대해(파티에 대한 참석자 배열을 통해 조회), 아직 거짓말을 할 수 있는 사람은 => 모두 진  실을 들은 것으로 표시하고 queu에 push

   3. 거짓 파티로 지정되어 있는 개수를 카운트 후 리턴

 

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

int N, M;
vector<int> partyToPerson[51];
vector<int> personToParty[51];
bool truthKnowPerson[51];
bool falsehoodParty[51];
queue<int> checkPersonQ;

void InputAndInit() {
	cin >> N >> M;
	for (int i = 0; i < 51; i++) {
		partyToPerson[i].clear();
		personToParty[i].clear();
		truthKnowPerson[i] = false;
		falsehoodParty[i] = true;
	}
	while (!checkPersonQ.empty())
		checkPersonQ.pop();

	//진실을 아는 사람
	int tmp, kownPerson;
	cin >> tmp;
	for (int i = 0; i < tmp; i++) {
		cin >> kownPerson;
		truthKnowPerson[kownPerson] = true;
		checkPersonQ.push(kownPerson);
	}

	int candidatePerson;
	//파티 참석자
	for (int partyNum = 1; partyNum <= M; partyNum++) {
		cin >> tmp;
		for (int i = 0; i < tmp; i++) {
			cin >> candidatePerson;
			partyToPerson[partyNum].push_back(candidatePerson);
			personToParty[candidatePerson].push_back(partyNum);
		}
	}
}

int main() {
	InputAndInit();

	while (!checkPersonQ.empty()) {
		int truthPerson = checkPersonQ.front(); checkPersonQ.pop();
		for(int nextParty : personToParty[truthPerson]){				//진실을 알고있는 사람이 참석한 모든 파티에 대해
			if (falsehoodParty[nextParty]) {							//아직 거짓말 파티를
				falsehoodParty[nextParty] = false;						//진실된 파티로 바꾸고								
				for (int nextTruthPerson : partyToPerson[nextParty]) {	//바꾼 진실된 파티에 참석한 모든 사람에 대해
					if (truthKnowPerson[nextTruthPerson] == false) {	//아직 이 사람이 진실을 모른다면
						truthKnowPerson[nextTruthPerson] = true;		//진실을 알도록 표시 후
						checkPersonQ.push(nextTruthPerson);				//큐에 넣어서 다음 번에 이 사람이 참석한 파티에 대해 알아본다.
					}
				}
			}
		}
	}
	int answer = 0;
	for (int i = 1; i <= M; i++) {
		if (falsehoodParty[i])
			answer++;
	}
	cout << answer << "\n";
	return 0;
}

 

 

 

'algorithm > boj' 카테고리의 다른 글

백준 2407 조합  (0) 2021.10.03
백준 11779 최소비용 구하기 2  (0) 2021.10.03
백준 13549 숨바꼭질 3  (0) 2021.10.03
백준 2638 치즈  (0) 2021.10.02
백준 1238 파티  (0) 2021.10.02

댓글