페이지

11375번: 열혈강호

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


#include<stdio.h>
#include<algorithm>
#include<vector>
using namespace std;
vector<int> adj[1001];
int rev[1001], n, m;
bool ck[1001];
bool dfs(int h) {
    if (ck[h]) return false;
    ck[h] = true;
    for (auto t : adj[h]) {
        if (!rev[t] || dfs(rev[t])) {
            rev[t] = h;
            return true;
        }
    }
    return false;
}
int main() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++) {
        int a, b;
        scanf("%d", &a);
        for (int j = 0; j < a; j++) {
            scanf("%d", &b);
            adj[i].push_back(b);
        }
    }
    int res = 0;
    for (int i = 1; i <= n; i++) {
        fill(ck + 1, ck + 1 + n, false);
        if (dfs(i)) res++;
    }
    printf("%d", res);
    return 0;
}

댓글 2개 :

  1. 이분 매칭 알고리즘을 이 문제로 간단히 설명해주실수 있나요?ㅠㅠrev[t] = h; 이 식은 네트워크 플로우에 쓰이는 식인데 어떻게 이분 매칭알고리즘에 적용했는지 알고 싶습니다. 그리고 저는 이분 그래프를 인접 행렬로 구현하는데 인접 리스트로 구현하는 방법도 알려주세요ㅠㅠ

    답글삭제
  2. 늦게 답하게 되었네요.
    rev[x]=h에서 x는 대응받는 원소이고 h는 대응시키는 원소인 것을 알 수 있습니다. 이분매칭의 특성상 계산 도중에 나가는 간선이 많아야 하나일 수 밖에 없어서 인접 행렬을 쓰지 않고 rev를 사용할 수 있습니다. 인접리스트는 가능한 대응관계를 저장할 뿐입니다.
    자세한 설명은 시간상 힘들고 스택오버플로 같은 사이트에서 찾아보는 것을 권장합니다.

    답글삭제