二部图
二部图的最大匹配:
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 }