Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Tags more
Archives
Today
Total
관리 메뉴

개발자 일기장.

백준 1043문제. 거짓말 본문

취업/Algorithm.

백준 1043문제. 거짓말

Azderica 2020. 3. 1. 08:07

거짓말

 


Problem?

지민이는 파티에 가서 이야기하는 것을 좋아한다. 파티에 갈 때마다, 지민이는 지민이가 가장 좋아하는 이야기를 한다. 지민이는 그 이야기를 말할 때, 있는 그대로 진실로 말하거나 엄청나게 과장해서 말한다. 당연히 과장해서 이야기하는 것이 훨씬 더 재미있기 때문에, 되도록이면 과장해서 이야기하려고 한다. 하지만, 지민이는 거짓말쟁이로 알려지기는 싫어한다. 문제는 몇몇 사람들은 그 이야기의 진실을 안다는 것이다. 따라서 이런 사람들이 파티에 왔을 때는, 지민이는 진실을 이야기할 수밖에 없다. 당연히, 어떤 사람이 어떤 파티에서는 진실을 듣고, 또 다른 파티에서는 과장된 이야기를 들었을 때도 지민이는 거짓말쟁이로 알려지게 된다. 지민이는 이런 일을 모두 피해야 한다.

사람의 수 N이 주어진다. 그리고 그 이야기의 진실을 아는 사람이 주어진다. 그리고 각 파티에 오는 사람들의 번호가 주어진다. 지민이는 모든 파티에 참가해야 한다. 이때, 지민이가 거짓말쟁이로 알려지지 않으면서, 과장된 이야기를 할 수 있는 파티 개수의 최댓값을 구하는 프로그램을 작성하시오.

 

 

Input

첫째 줄에 사람의 수 N과 파티의 수 M이 주어진다.

둘째 줄에는 이야기의 진실을 아는 사람의 수와 번호가 주어진다. 진실을 아는 사람의 수가 먼저 주어지고 그 개수만큼 사람들의 번호가 주어진다. 사람들의 번호는 1부터 N까지의 수로 주어진다.

셋째 줄부터 M개의 줄에는 각 파티마다 오는 사람의 수와 번호가 같은 방식으로 주어진다.

N, M은 50 이하의 자연수이고, 진실을 아는 사람의 수와 각 파티마다 오는 사람의 수는 모두 0 이상 50 이하의 정수이다.

 

Output

첫째 줄에 문제의 정답을 출력한다.

 

Solution

함께 여러 파티에 참석하는 사람들을 연결한다.

그 후 진실을 아는 사람을 연결시킨 후 아무런 관계가 없는 파티만 남긴다.

가정

isTrue : 사실을 아는 파티

isKnowTrue : 사실을 아는 사람들 

 

Code

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

#define MAX 50 + 1

vector<int> party[MAX];
bool isTrue[MAX];
bool isKnowTrue[MAX];


int main() {
	int n, m, truth_size;
	int num;

	cin >> n >> m;
	cin >> truth_size;

	// get info who is knowing true
	for (int i = 0; i < truth_size; i++) {
		scanf("%d", &num);
		isKnowTrue[num] = true;
	}

	// get party info
	int partyNum;
	for (int i = 0; i < m; i++) {
		scanf("%d", &partyNum);
		for (int j = 0; j < partyNum; j++) {
			scanf("%d", &num);
			party[i].push_back(num);
		}
	}

	// check when there is no changing
	bool next = true;
	while (next) {
		next = false;
		for (int i = 0; i < m; i++) if (!isTrue[i]) {
			bool flag = false;
			// check someone in party that knows true 
			for (int x : party[i]) if (isKnowTrue[x]) {
				flag = true;
				break;
			}	
			if (flag) {
				isTrue[i] = true;
				next = true;
				// change all memberin party to true man
				for (int x : party[i])	
					isKnowTrue[x] = true;
			}
		}
	}

	int ans = 0;
	for (int i = 0; i < m; i++) if (!isTrue[i])
		ans++;
	cout << ans << "\n";

	return 0;
}

 


똑똑한 사람들이 너무 많다.

'취업 > Algorithm.' 카테고리의 다른 글

백준 2448. 별 찍기 - 11  (0) 2020.03.03
백준 16953문제. A→B  (0) 2020.03.02
백준 15657문제. N과 M (8)  (0) 2020.02.28
백준 15652문제. N과 M (4)  (0) 2020.02.28
백준 2167문제.  (0) 2020.02.24