Doby's Lab

백준 1298번: 노트북의 주인을 찾아서 (C++) 본문

PS/BOJ

백준 1298번: 노트북의 주인을 찾아서 (C++)

도비(Doby) 2022. 3. 19. 19:14

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

 

1298번: 노트북의 주인을 찾아서

어느 날 모든 학생들은 한 명이 한개의 노트북을 가지고 공부하던 도중, 자리를 바꾸다가 그만 노트북이 뒤섞이고 말았다. 대다수의 학생들은 자신의 노트북을 잘 알고 있어서 자신의 노트북을

www.acmicpc.net


Solved By:  Bipartite Matching

 

처음으로 이분 매칭 알고리즘을 사용했습니다. DFS의 리턴형이 bool인 함수를 구현하여 각 정점이 이어질 수 있는 지를 파악합니다. Time Complexity는 O(VE)입니다. 또 다른 이분 매칭 알고리즘들이 있다는데 알아보아야겠습니다.

 

처음 구현을 하여서 각 코드마다 어떤 역할인지 주석으로 달아두었습니다.

#include <iostream>
#include <vector>
#include <memory.h>
#define MAX 101
using namespace std;

int n, m;
vector<int> adj[MAX]; // 연결된 간선들 저장
bool visited[MAX]; //
int occupy[MAX]; // 어떠한 정점을 occupy(차지)하고 있는 정점의 정보

bool dfs(int node){
    for(int i = 0; i < adj[node].size(); i++){
        int next = adj[node][i];
        
        if(visited[next]) continue;
        // (biMatch는 실행될 때마다 visited가 memset에 의해 초기화된다)
        // 즉, biMatch가 실행되면서 위 조건에 의해 continue가 되는 경우는
        // 점유되어 있는 정점을 recursive call에 의해 건드렸다는 소리가 된다.
        // 하나의 점유 정점을 여러 개의 출발 정점에서 건드리는 것은
        // 이분 매칭의 의도에 엇나가므로 다음 조건이 필요하다.
        visited[next] = true;
        
        if(occupy[next] == 0 || dfs(occupy[next])){
        // 1. 현재 next vertex를 occupy하고 있는 정점이 없다
        // 2. 현재 next vertex를 occupy하고 있는 정점이
        // 다른 vertex로 갈 수 있다
            occupy[next] = node;
            return true;
        }
    }
    return false;
}

int main(){
    cin >> n >> m;
    
    int a, b;
    for(int i = 0; i < m; i++){
        cin >> a >> b;
        adj[a].push_back(b);
    }
    
    int result = 0;
    for(int i = 1; i <= n; i++){
        memset(visited, false, sizeof(visited));
        if(dfs(i)) result++;
    }
    
    cout << result;
    return 0;
}
728x90

'PS > BOJ' 카테고리의 다른 글

백준 12833번: XORXORXOR (C++)  (0) 2022.03.19
백준 11375번: 열혈강호 (C++)  (0) 2022.03.19
백준 16404번: 주식회사 승범이네 (C++)  (0) 2022.03.19
백준 14268번: 회사 문화 2 (C++)  (0) 2022.03.19
백준 6086번: 최대 유량 (C++)  (0) 2022.03.19