이분 그래프의 최대 일치 (헝가리 알고리즘 및 Dinic 알고리즘)

이분 그래프의 최대 일치 :

이분 그래프가 주어지면 왼쪽에 여러 노드가 있고 오른쪽에 여러 노드가 있으며 왼쪽에있는 노드는 오른쪽에있는 노드와 일치한다고 생각하고 왼쪽에있는 각 노드에는 선택할 수있는 여러 개체가 있으며 각 노드는 왼쪽은 선택 가능 오른쪽 노드, 각 오른쪽 노드는 한 번만 선택할 수 있습니다. 이제 왼쪽에 몇 개의 노드가 일치 할 수 있는지 물어보십시오.

일반적으로 한 무리의 사람들과 상금이 있습니다. 모두가 좋아하는 상을 가지고 있습니다. 각 종류의상은 하나뿐입니다. 여러분이 가장 좋아하는 상을 얼마나받을 수 있는지 물어보십시오 (각 사람은 하나만받을 수 있고, 각 사람은 좋아하는 상품이 여러 개있을 수 있습니다)?

헝가리 알고리즘 :

헝가리 알고리즘의 접근 방식은 각 왼쪽 노드를 먼저 일치시키는 것이며 일치하지 않는 오른쪽 노드가 있으면 직접 일치합니다. 그렇지 않으면 오른쪽에있는 일치 노드의 매처에게 다른 옵션이 있는지 확인하십시오.
이야기

#include<bits/stdc++.h>

using namespace std;
const int maxn = 1e5 + 5;
int n1,n2,u,v,m,mat[maxn],st[maxn];//mat数组表示第i个节点是否被匹配,如果是0则是没被匹配
int h[maxn],e[maxn],nex[maxn],cnt = 1;

void add(int a, int b){
    
    
    e[cnt] = b;
    nex[cnt] = h[a];
    h[a] = cnt++;
}

int findE(int x){
    
    
    for(int i = h[x]; i != 0; i = nex[i]){
    
    
        int endd = e[i];
        if(!st[endd]){
    
    
            st[endd] = 1;
            if(mat[endd] == 0 || findE(mat[endd])){
    
    //没被匹配,或者匹配的人还有别的选择,则当前节点可以匹配此节点
                mat[endd] = x;
                return 1;
            }
        }
    }
    return 0;
}

int main(){
    
    
    cin >> n1 >> n2 >> m;
    int a,b,ans = 0;
    while(m--){
    
    
        cin >> a >> b;
        add(a,b);
    }
    for(int i = 1; i <= n1; i++){
    
    
        memset(st,0,sizeof st);
        if(findE(i))ans++;//匹配到了匹配数目就加一
    }
    cout << ans << endl;
}

Dinic 알고리즘

Dinic은 네트워크 흐름 알고리즘이며 이분 그래프 일치에도 사용할 수 있습니다. 오른쪽 노드를 싱크 포인트에, 왼쪽 노드를 소스 포인트에 연결 한 다음 왼쪽과 오른쪽 관련 노드를 연결할 수 있으므로 그래프가 작성되고 각 에지의 용량은 1이됩니다.

오른쪽에있는 노드가 싱크 지점에 연결되어 있음을 알 수 있습니다. 즉, 싱크 지점에 도달하려면 오른쪽 지점을 통과해야합니다. 오른쪽 지점에 도달하려면 통과해야합니다. 일치 효과를 얻을 수 있습니다.
좌석 배치
상대적으로 알몸의 질문, Dinic을 쓰는 것이 옳습니다.

추천

출처blog.csdn.net/qq_36102055/article/details/107384118