이분 그래프의 최대 일치 :
이분 그래프가 주어지면 왼쪽에 여러 노드가 있고 오른쪽에 여러 노드가 있으며 왼쪽에있는 노드는 오른쪽에있는 노드와 일치한다고 생각하고 왼쪽에있는 각 노드에는 선택할 수있는 여러 개체가 있으며 각 노드는 왼쪽은 선택 가능 오른쪽 노드, 각 오른쪽 노드는 한 번만 선택할 수 있습니다. 이제 왼쪽에 몇 개의 노드가 일치 할 수 있는지 물어보십시오.
일반적으로 한 무리의 사람들과 상금이 있습니다. 모두가 좋아하는 상을 가지고 있습니다. 각 종류의상은 하나뿐입니다. 여러분이 가장 좋아하는 상을 얼마나받을 수 있는지 물어보십시오 (각 사람은 하나만받을 수 있고, 각 사람은 좋아하는 상품이 여러 개있을 수 있습니다)?
헝가리 알고리즘 :
헝가리 알고리즘의 접근 방식은 각 왼쪽 노드를 먼저 일치시키는 것이며 일치하지 않는 오른쪽 노드가 있으면 직접 일치합니다. 그렇지 않으면 오른쪽에있는 일치 노드의 매처에게 다른 옵션이 있는지 확인하십시오.
이야기
#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을 쓰는 것이 옳습니다.