본문 바로가기

백준

백준11375 - 열혈강호

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

 

11375번: 열혈강호

강호네 회사에는 직원이 N명이 있고, 해야할 일이 M개가 있다. 직원은 1번부터 N번까지 번호가 매겨져 있고, 일은 1번부터 M번까지 번호가 매겨져 있다. 각 직원은 한 개의 일만 할 수 있고, 각각의 일을 담당하는 사람은 1명이어야 한다. 각각의 직원이 할 수 있는 일의 목록이 주어졌을 때, M개의 일 중에서 최대 몇 개를 할 수 있는지 구하는 프로그램을 작성하시오.

www.acmicpc.net

이분 매칭을 이용하여 풀었다. 나동빈님 블로그에서 참고하였다. 이분 매칭은 a 집단에서 b 집단을 일대일로 각 원소를 매칭하는데 최대로 매칭해 줄 수 있는 방법을 찾는 방법이다. dfs를 이용하여 구현한다.  구현 원리는 임의의 점이 도착하려는 자리에 어떤 원소가 이미 도착했다면 다른 곳으로 옮겨갈 수 있는지 판별하고 옮겨갈 수 있는 점이 있다면 그 점으로 이동시키고 현재 들어가려는 원소를 넣어준다.

 

#include <iostream>
#include <vector>
#define MAX 1001
using namespace std;

vector<int> a[MAX]; //각각의 노드 v[x][y]면 x에서 y를 선택한다는 뜻
int d[MAX]; //각 출발점에서 도착점을 담을 공간
bool c[MAX]; //특정한 정점을 처리했는지 확인하는 변수
int N, M;
int num;
int work;
int cnt = 0;

bool dfs(int x) {
	for (int i = 0; i < a[x].size(); i++) {
		int t = a[x][i];

		if (c[t]) { //이번 순서에서 이미 t점에 방문 한 적이 있으면
			continue; //무시
		}

		c[t] = true; //t점을 방문처리

		if (d[t] == 0 || dfs(d[t])) { //아직 t점으로 도착한 점이 없거나 다른 이미 점유하고 있는 점에서 다른 곳으로 이동할 곳이 있으면
			d[t] = x; //현재 점 x를 t에 도달할 수 있다고 지정
			return true; //매칭 성공
		}
	}
	return false; //매칭 실패
}

int main() {
	cin >> N >> M;
	for (int i = 1; i <= N; i++) {
		cin >> num;
		for (int j = 0; j < num; j++) {
			cin >> work;
			a[i].push_back(work);
		}
	}

	for (int i = 1; i <= N; i++) {
		fill(c, c + MAX, false);

		if (dfs(i)) { //매칭이 성공되면
			cnt++; //성공된 매칭의 갯수 증가
		}
	}

	cout << cnt;
}

'백준' 카테고리의 다른 글

백준14225 - 부분수열의 합  (0) 2020.02.10
백준15663 - N과 M(9)  (0) 2020.02.05
백준11060 - 점프 점프  (0) 2020.02.04
백준1697 - 숨바꼭질  (0) 2020.02.03
백준9251 - LCS  (0) 2020.02.02