二部图

二部图的最大匹配:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long ll;
 5 const int inf=0x3f3f3f3f;
 6 const int maxn = 3000;
 7 int edge[maxn][maxn];//edge[i][j] == 1 代表i,j可以匹配
 8 int vis[maxn];//用来记录该点是否被访问过
 9 int cx[maxn], cy[maxn];//用来记录x集合中匹配的y元素是哪个
10 int nx, ny;//nx表示x集合的顶点个数, ny表示y集合的顶点个数
11 
12 int line(int u){
13     int v;
14     for(v = 1; v <= ny; v++){
15         if(edge[u][v] && !vis[v]){
16             vis[v] = 1;
17             if(cy[v] == -1 || line(cy[v])){//如果y集合中的v没有匹配或v已经匹配,但从cy[v]中可以找到一条增广路
18                 cx[u] = v;//找到增广路,修改匹配
19                 cy[v] = u;
20                 return 1;
21             }
22         }
23     }
24     return 0;
25 }
26 
27 int maxmatch(){
28     int sum = 0, i;
29     memset(cx, 0xff, sizeof(cx));//初始值为-1表示两个集合中都没有匹配的元素
30     memset(cy, 0xff, sizeof(cy));
31     memset(vis, 0, sizeof(vis));//重置标记为未访问
32     for(i = 1; i <= nx; i++){
33         if(cx[i] == -1){//还没被匹配就执行内部代码
34             memset(vis, 0, sizeof(vis));//重置标记为未访问
35             sum += line(i);//以 i 为起点开始查找增广路,返回true ,匹配数+1
36         }
37     }
38     return sum;
39 }
40 int main(){
41     int x, y, t,a,ans;
42     scanf("%d %d %d", &nx, &ny, &t);
43     memset(edge, 0, sizeof(edge));
44     for(int j=1;j<=nx;j++){
45         cin>>a;
46         for(int i = 0; i < a; i++){
47             scanf("%d", &x);
48             edge[j][x] = 1;
49         }
50     }
51     int sum = maxmatch();
52     printf("%d\n", sum);
53     return 0;
54 }

 

posted @ 2019-10-28 16:55  yya雨  阅读(178)  评论(0编辑  收藏  举报