二分图的最大独立集 最大匹配解题 Hopcroft-Karp算法

  二分图模型中的最大独立集问题:在二分图G=(X,Y;E)中求取最小的顶点集V* ⊂ {X,Y},使得边 V*任意两点之间没有边相连。

  公式: 最大独立集顶点个数 = 总的顶点数(|X|+|Y|)- 最大匹配数

  poj3692

  题意:幼儿园有G个小女孩和B个小男孩,小女孩彼此之间互相认识,小男孩彼此之间互相认识。一些小女孩与一些小男孩之间也互相认识。现在老师要选一些小朋友做一个游戏,这些小朋友之间必须互相认识。问老师最多可以选多少个小朋友。

  解题:满足X集合,Y集合,E边集合的题目可以用二分图模型来解。此题中的E={(i,j)| i与j相互不认识}。所有图初始为1,输入边则改为0。这样求最大匹配。

  关于为什么要这样构图:X(Y)中都是相互认识的,也就是有关系的(有边相连)。但是二分图中X(Y)中的点之间是没有关系,是独立的点。所以建边的时候要反过来。

  看看别人的博客怎么说: http://www.2cto.com/kf/201401/273879.html

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7
 8 const int N=1005,INF=0x3f3f3f3f;
 9 int bmap[N][N],cx[N],cy[N],dx[N],dy[N];
10 bool bmask[N];
11 int nx,ny,dis,ans;
12 bool searchpath()
13 {
14     queue<int> q;
15     dis=INF;
16     memset(dx,-1,sizeof(dx));
17     memset(dy,-1,sizeof(dy));
18     for(int i=1;i<=nx;i++)
19     {
20         if(cx[i]==-1){ q.push(i); dx[i]=0; }
21         while(!q.empty())
22         {
23             int u=q.front(); q.pop();
24             if(dx[u]>dis) break;
25             for(int v=1;v<=ny;v++)
26             {
27                 if(bmap[u][v]&&dy[v]==-1)
28                 {
29                     dy[v]= dx[u] + 1;
30                     if(cy[v]==-1) dis=dy[v];
31                     else
32                     {
33                         dx[cy[v]]= dy[v]+1;
34                         q.push(cy[v]);
35                     }
36                 }
37             }
38         }
39     }
40     return dis!=INF;
41 }
42 int findpath(int u)
43 {
44     for(int v=1;v<=ny;v++)
45     {
46         if(!bmask[v]&&bmap[u][v]&&dy[v]==dx[u]+1)
47         {
48             bmask[v]=1;
49             if(cy[v]!=-1&&dy[v]==dis) continue;
50             if(cy[v]==-1||findpath(cy[v]))
51             {
52                 cy[v]=u; cx[u]=v;
53                 return 1;
54             }
55         }
56     }
57     return 0;
58 }
59 void maxmatch()
60 {
61     ans=0;
62     memset(cx,-1,sizeof(cx));
63     memset(cy,-1,sizeof(cy));
64     while(searchpath())
65     {
66         memset(bmask,0,sizeof(bmask));
67         for(int i=1;i<=nx;i++)
68             if(cx[i]==-1) ans+=findpath(i);
69     }
70 }
71 int main()
72 {
73     //freopen("test.txt","r",stdin);
74     int m,i,j,k=1,cas;
75     while(scanf("%d%d%d",&nx,&ny,&m)!=EOF)
76     {
77         if(!nx) break;
78         for(i=1;i<=nx;i++)
79             for(j=1;j<=ny;j++)
80                 bmap[i][j]=1;
81         while(m--)
82         {
83             scanf("%d%d",&i,&j);
84             bmap[i][j]=0;
85         }
86         maxmatch();
87         printf("Case %d: ",k++);
88         printf("%d\n",nx+ny-ans);
89     }
90     return 0;
91 }

 

时间: 2024-08-29 07:40:43

二分图的最大独立集 最大匹配解题 Hopcroft-Karp算法的相关文章

hdu2389二分图之Hopcroft Karp算法

You're giving a party in the garden of your villa by the sea. The party is a huge success, and everyone is here. It's a warm, sunny evening, and a soothing wind sends fresh, salty air from the sea. The evening is progressing just as you had imagined.

【二分图】【最大匹配】【匈牙利算法】洛谷 P2071 座位安排 seat.cpp/c/pas

∵每个座位可以坐俩人,所以拆点最大匹配. 1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 using namespace std; 5 #define N 2001 6 vector<int>G[N<<2]; 7 typedef vector<int>::iterator ITER; 8 int mat[N<<2]; 9 bool vis[N<&

【二分图】【最大匹配】【匈牙利算法】bzoj1191 [HNOI2006]超级英雄Hero

裸的最大匹配. 1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 using namespace std; 5 vector<int>G[2002]; 6 typedef vector<int>::iterator ITER; 7 int n,m,mat[2002],x,y; 8 bool vis[2002]; 9 bool dfs(int U) 10 { 11 for(ITE

【二分图】【最大匹配】【匈牙利算法】CODEVS 2776 寻找代表元

裸的匈牙利,存模板. 1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 using namespace std; 5 #define N 201 6 int n,m,x; 7 vector<int>G[N<<1]; 8 typedef vector<int>::iterator ITER; 9 int mat[N<<1]; bool vis[N<&

POJ1325_Machine Schedule(二分图/最小点覆盖=最大匹配)

解题报告 http://blog.csdn.net/juncoder/article/details/38147135 题目传送门 题意: A机器有n个模式,B机器有m个模式,每个作业可以在任何机器的特定模式下工作,转换模式需要耗时,求最小耗时 思路: 把AB两机器的模式当成二分图顶点,模式之间的连线就是某个作业可以在该两个模式下工作,就转换成求最小点覆盖,用最少的点覆盖最多的边. 最小点覆盖=最大匹配 #include <queue> #include <cmath> #incl

HDU2119_Matrix(二分图/最小点覆盖=最大匹配)

解题报告 题目传送门 题意: 题意类似与POJ3041 思路: 见POJ3041解题报告 最小点覆盖. #include <iostream> #include <cstring> #include <cstdio> using namespace std; int mmap[110][110],vis[110],pre[110],n,m; int dfs(int x) { for(int i=1; i<=m; i++) { if(!vis[i]&&

hdu3829 二分图的最大独立集

http://acm.hdu.edu.cn/showproblem.php?pid=3829 Cat VS Dog Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) Total Submission(s): 2851    Accepted Submission(s): 972 Problem Description The zoo have N cats and M dogs

二分图中的最大匹配数等于最小点覆盖数的证明

转载自Matrix67 二分图最大匹配的K?nig定理及其证明 如果你看不清楚第二个字母,下面有一个大号字体版本: 二分图最大匹配的K?nig定理及其证明 本文将是这一系列里最短的一篇,因为我只打算把K?nig定理证了,其它的废话一概没有.    以下五个问题我可能会在以后的文章里说,如果你现在很想知道的话,网上去找找答案:    1. 什么是二分图:    2. 什么是二分图的匹配:    3. 什么是匈牙利算法:(http://www.matrix67.com/blog/article.as

「CODVES 1922 」骑士共存问题(二分图的最大独立集|网络流)&amp;dinic

首先是题目链接  http://codevs.cn/problem/1922/ 结果发现题目没图(心情复杂 然后去网上扒了一张图 大概就是这样了. 如果把每个点和它可以攻击的点连一条边,那问题就变成了求二分图的最大独立集了 (二分图最大独立集:即一个点集,集合中任两个结点不相邻),然后就是建图了. 题图非常好心的帮忙染色了,所以我们可以看出来,一个点可以到达的点和它的颜色是不一样的,所以只需要黑白染色就可以了,然后把黑点看作一个集合, 白点看作一个集合,又因为二分图最大独立集= 二分图最大匹配,