匈牙利算法

 1 /**\
 2 https://www.luogu.com.cn/problem/P3386
 3 二分图最大匹配匈牙利算法:
 4 假设左部是男孩,右部是女孩
 5 1、对于一个男孩子,如果他喜欢女孩y,女孩y没有配偶,就在一起
 6 2、如果y有配偶了,x还是想去挖一手墙脚,y也不是什么好女人,
 7 如果y发现他的配偶z能换一个对象(这里dfs),y就主动抛弃z(z能换一个对象),跟x在一起
 8 这样就多了一对配偶
 9 \**/
10 #include <bits/stdc++.h>
11 using namespace std;
12 #define fi first
13 #define se second
14 #define go continue
15 #define int long long
16 #define PII pair<int, int>
17 #define sf(x) scanf("%lld",&x)
18 #define ytz int _; sf(_); while(_--)
19 #define fory(i,a,b) for(int i = a; i <= b; ++i)
20 #define forl(i,a,b) for(int i = a; i >= b; --i)
21 #define debug(a) cout << #a << " = " << a <<endl;
22 const int N = 1010;
23 int n, m, e;
24 int g[N][N], vis[N], link[N];
25 //dfs搜索的起点是左集合, link[]代表右集合
26 int dfs(int x)
27 {
28     fory(i, 1, m)
29     {
30         if(!g[x][i] || vis[i]) go; //如果没有边 或者已经被邀请过了 就跳过
31         vis[i] = 1;
32         if(link[i] == 0 || dfs(link[i])) //如果没有配偶,或者能让自己的配偶找到配偶(找到增广路),就在一起
33         {
34             link[i] = x;
35             return 1;
36         }
37     }
38     return 0;
39 }
40 signed main()
41 {
42     int ok = 0;
43     sf(n), sf(m), sf(e);
44     fory(i, 1, e)
45     {
46         int x, y;
47         sf(x), sf(y);
48         g[x][y] = 1;
49     }
50     fory(i, 1, n)
51     {
52         memset(vis, 0, sizeof vis);
53         if(dfs(i)) ok++;//如果能匹配成功,边数++
54     }
55     printf("%lld\n", ok);
56     return 0;
57 }

 

posted @ 2022-03-04 15:10  std&ice  阅读(71)  评论(0编辑  收藏  举报