baekjoon

[백준] 14433 한조 대기 중

윤만석 2023. 6. 7. 11:21

문제

그랜드마스터 승급까지 1승이 남은 욱제는 끔찍한 광경을 보고야 말았다. 팀원들이 게임을 던지기 시작한 것이다.

그렇게 승급을 포기하려던 찰나, 욱제는 적 팀도 던진다는 사실을 알아챘다! 이제 승부는 미궁 속으로 빠지게 되었다.

한 팀에는 N명의 플레이어가 있고, 각 팀원은 게임을 시작하기 전에 영웅을 한 명 선택한다. 이때 같은 팀에서 여러 명이 한 영웅을 선택할 수는 없다. 게임에는 수많은 영웅이 있고, 그 중 M개의 영웅은 게임의 승패를 결정지을 정도로 구린 영웅이다. 이런 영웅을 선택하는 것을 트롤픽이라고 불린다. (같은 게임이기 때문에 트롤픽의 수 M은 양 팀 모두 동일하다)

양 팀이 모두 게임을 던지자, 즐겜 분위기가 형성되었다. 각 팀원은 M개의 트롤픽 중 자신이 원하는 트롤픽들을 말하고, 자기 팀에서 최대한 많은 팀원이 즐겜을 할 수 있도록 트롤픽을 분배한다. 트롤픽을 하지 못한 팀원은 아쉽지만 힐러를 고르게 된다.

게임은 비슷한 실력의 팀원을 매칭시켜 주기 때문에, 결국 트롤픽을 더 적게 한 팀이 이기게 된다. 각 팀의 팀원들이 고르고 싶어하는 트롤픽의 리스트가 주어질 때, 욱제가 그랜드마스터를 찍을 수 있는지 알아보자. (비기면 점수를 안 주기 때문에 승급 할 수 없으며, 물론 욱제도 게임을 던진다)

 

N명의 플레이어와 M개의 트롤픽의 최대 매칭을 구하는 이분매칭 문제입니다.

두개의 팀에대해 이분매칭을 수행하고, 욱제의 팀에있는 트롤픽이 상대팀보다 적으면 됩니다.

#include<bits/stdc++.h>
#define FAST ios_base::sync_with_stdio(false),cin.tie(NULL);
#define mset(v) memset(v,0,sizeof(v));
#define rep(i,a) for(int i=0;i<a;++i)
#define REP(i,a) for(int i=1;i<=a;++i)
#define all(v) v.begin(), v.end()
using namespace std;

typedef long long ll;
typedef pair<int, int> pi;
typedef tuple<int, int, int>ti;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
int dy[] = { -1,0,1,0 }, dx[] = { 0,1,0,-1 }, INF = 987654321;

int N, M, K1, K2, x, y, v1[301], v2[301], s1[301], s2[301];
vi adj[301], adj2[301];
bool dfs1(int t) {
	if (v1[t])return 0;
	v1[t] = 1;
	for (int r : adj[t]) {
		if (!s1[r] || dfs1(s1[r])) {
			s1[r] = t;
			return 1;
		}
	}
	return 0;
}
bool dfs2(int t) {
	if (v2[t])return 0;
	v2[t] = 1;
	for (int r : adj2[t]) {
		if (!s2[r] || dfs2(s2[r])) {
			s2[r] = t;
			return 1;
		}
	}
	return 0;
}
int main() {
	FAST;
	cin >> N >> M >> K1 >> K2;
	while (K1--) {
		cin >> x >> y;
		adj[x].push_back(y);
	}
	while (K2--) {
		cin >> x >> y;
		adj2[x].push_back(y);
	}
	int cnt1 = 0, cnt2 = 0;
	REP(i, N) {
		mset(v1);
		mset(v2);
		if (dfs1(i))cnt1++;
		if (dfs2(i))cnt2++;
	}
	if (cnt1 < cnt2)cout << "네 다음 힐딱이";
	else cout << "그만 알아보자";
}