Luo Gu P3386 [template] bipartite graph matching (Hungary algorithm, augmenting path)

Portal


Hungarian algorithm

Hungarian algorithm (alias "find the object game"), is to give you a bipartite graph, find the maximum matching.

The maximum match is even able to do more than the number of edges.

We call this abstract concept into reality problem - find the object.

Men and women into two groups, A group of boys and girls group B, each boy has his own favorite girls (probably more than one), as your God, as much as possible so that more people become boyfriend and girlfriend.

How to do it?

Enumerate every boy, asked to find a girlfriend as much as possible, but to ensure that the person in front of his girlfriend can be replaced, but the original has a girlfriend now must have a girlfriend, so if can do it, then the answer +1.

Enumerate all the boys after getting the answer.

This is the main idea of the algorithm Hungary - augmenting paths .

Offer summer camp zyb teacher courseware:

 

 AC Code

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstdio>
 5 #include<cstring>
 6 using namespace std;
 7 const int maxn=1000005;
 8 int n,m,E,p[2005],cnt,ans;
 9 bool vis[2005];
10 int girl[2005];
11 struct node{
12     int v,next;
13 }e[2*maxn];
14 void insert(int u,int v){
15     cnt++;
16     e[cnt].v=v;
17     e[cnt].next=p[u];
18     p[u]=cnt;
19 }
20 bool work(int u){
21     for(int i=p[u];i!=-1;i=e[i].next){
22         if(!vis[e[i].v]){
23             vis[e[i].v]=1;
24             if(!girl[e[i].v]||work(girl[e[i].v])){
25                 girl[e[i].v]=u;
26                 return true;
27             }
28         }
29     }
30     return false;
31 }
32 int main()
33 {
34     memset(p,-1,sizeof(p));
35     cin>>n>>m>>E;
36     for(int i=1;i<=E;i++){
37         int u,v;
38         scanf("%d%d",&u,&v);
39         if(u<=n&&v<=m){
40             insert(u,v+1000);
41             insert(v+1000,u);
42         }
43     }
44     for(int i=1;i<=n;i++){
45         memset(vis,0,sizeof(vis));
46         if(work(i)) ans++;
47     }
48     cout<<ans;
49     return 0;
50 }

Guess you like

Origin www.cnblogs.com/yinyuqin/p/12181706.html