简单地说,就是一张图里的所有点可以分为两组(如上图),并且每条边都跨越两组。这样的图就是二分图。
一个图为二分图仅当:没有奇数圈;点色数为 2。
交替路(也叫交错路):从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边……形成的路径叫交替路。
增广路:从一个未匹配点出发,走交替路,以另一个未匹配点为结尾(出发的点不算),则这条交替路称为增广路
增广路定理:任意一个非最大匹配的匹配一定存在增广路。
我们可以一直找增广路,不断交换匹配。根据增广路定理,如果找不到了,就说明已经达到最大匹配。
#include <iostream> #include <cstring> using namespace std; int map[100][100]; int ans=0; int visit[100],link[100]; int n,m; bool dfs(int x) { for(int i=1;i<=n;i++) { if(!visit[i]&&map[x][i]) { visit[i]=1; if(!link[i]||dfs(link[i])) { link[i]=x; return 1; } } } return 0; } int main() { cin>>n>>m; for(int i=1;i<=m;i++) { int x,y; cin>>x>>y; map[x][y]=1; } for(int i=1;i<=n;i++) { memset(visit,0,sizeof(visit)); if(dfs(i)) ans++; } cout<<ans; }