问题
二分图的最大匹配算法
解法
寻找一条交错路径,路径中的边进行翻转。
优化:1, 只要计算一个集合中的顶点。
2, 在每个顶点处,记录已经查找过的另一集合的顶点,防止重复。
#include <bits/stdc++.h>
using namespace std;
enum{maxn = 1000+5};
vector<int> G[maxn];
int color [maxn];
int res[maxn];
int visited[maxn];
// 传入集合A中的顶点。
bool findPath(int u)
{
for(int i=0; i<G[u].size(); ++i)
{
int v = G[u][i];
if (visited[v])//去除重复
continue;
visited[v] = 1;//记录已经查找过
if (res[v]==0 || findPath(res[v]))
{
res[u]= v, res[v]= u;
return true;
}
}
return false;
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
while(m--)
{
int a, b;
scanf("%d %d", &a, &b);
G[a].push_back(b);
G[b].push_back(a);
}
int colorNum = 0;
queue<int> q;
memset(color, -1, sizeof(color));
while(colorNum<n){
if (q.empty())
{
for (int i=1; i<=n; ++i)
{
if (color[i] == -1)
{
color[i]= 0;
colorNum++;
q.push(i);
break;
}
}
}
int now = q.front(); q.pop();
for (int i=0; i<G[now].size(); ++i)
{
if (color[G[now][i]]==-1)
{
color[G[now][i]] = !color[now];
colorNum++;
q.push(G[now][i]);
}else{
if(color[G[now][i]] == color[now])
return -1;
}
}
}
memset(res, 0, sizeof(res));
int ret = 0;
for(int i=1; i<=n; ++i)
{
if (color[i]==0)
{
memset(visited, 0, sizeof(visited));
if (findPath(i))
++ret;
}
}
printf("%d\n", ret);
return 0;
}