알고리즘

[Java] 백준 11376번 열혈강호2

J3SUNG 2023. 4. 10. 23:21
728x90

이분 매칭으로 문제를 해결하였습니다.

N명의 직원이 있고 해야할 일이 M개가 있을 때
직원들이 할 수 있는 일들이 정해져있고 두개의 일만 할 수 있습니다.
이 때 일을 잘 분배해서 가장 많이 할 수 있는 일의 수를 찾는 문제입니다.

A집단과 B집단을 매칭해야하는 경우이므로 이분매칭을 사용할 수 있습니다.

1. 매칭이 되어 있지 않으면 매칭
2. 매칭이 되어 있으면 매칭되어 있는 곳에서 다른 곳에 매칭이 되는지 확인
3. 불가능하면 다른 곳 매칭이 가능한지 확인
4. 모든 곳이 매칭 불가능하면 그 위치는 매칭이 안되는 곳으로 확인

각 사람당 DFS를 두번 돌리므로서 2개씩 일을 배치해 줄 수 있게 됩니다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.StringTokenizer;

public class Main {
	static int ans;
	static int n;
	static int m;
	static int work[];
	static int visit[];
	static ArrayList<ArrayList<Integer>> al = new ArrayList<>();

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		StringTokenizer st = new StringTokenizer(br.readLine());

		ans = 0;
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());
		work = new int[m + 1];
		visit = new int[n + 1];

		for (int i = 0; i <= n; ++i) {
			ArrayList<Integer> temp = new ArrayList<>();
			al.add(temp);
		}

		for (int i = 1; i <= n; ++i) {
			st = new StringTokenizer(br.readLine());
			int cnt = Integer.parseInt(st.nextToken());
			for (int j = 0; j < cnt; ++j) {
				al.get(i).add(Integer.parseInt(st.nextToken()));
			}
		}

		for (int i = 1; i <= n; ++i) {
			if(DFS(i) == 1) {
				++ans;
			}
			for(int j=1; j<=n; ++j) {
				visit[j] = 0;
			}
			if(DFS(i) == 1) {
				++ans;
			}
			for(int j=1; j<=n; ++j) {
				visit[j] = 0;
			}
		}

		bw.write(ans + "\n");
		bw.close();
	}

	public static int DFS(int user) {
		if (visit[user] == 1) {
			return 0;
		}
		visit[user] = 1;
		
		for (int i = 0; i < al.get(user).size(); ++i) {
			int job = al.get(user).get(i);

			int next = work[job];
			if (work[job] == 0 || DFS(next) == 1) {
				work[job] = user;
				return 1;
			}
		}
		return 0;
	}
}