希望大家都知道哈子是二分图。二分图就是两队节点,内部互不相连,两堆节点之间有边相连。
二分图匹配
根据其性质易得图中只存在长度为偶数环,可用涂色法,把和该节点相对的节点设成不同的颜色,这样在同一堆的节点颜色相同,假如有矛盾,就不是二分图
这里是邻接表版。
int n;//节点数
vector<int> G[N];//G[i]表示i节点邻接的点,就是邻接表
int color[N];//color[i]=0,1,2 表i节点不涂颜色、涂白色、涂黑色
bool bipartite(int u)//判断无向图是否可二分
{
for(int i=0;i<G[u].size();i++)//枚举结点
{
int v=G[u][i];//相邻节点
if(color[v]==color[u])//若两结点颜色相同,无法二分
return false;
if(!color[v])//若结点没涂颜色
{
color[v]=3-color[u];//改变结点颜色,使v的颜色与u的颜色对立
if(!bipartite(v))//若点v不满足二分图话,则无法二分
return false;
}
}
return true;
}
二分图判定
思路很好想,就是贪心,却取名叫匈牙利算法
1设所有边都为非匹配边
2寻找增广路,得到更大匹配
若可直接找到,直接匹配
否则看其它点能不能“让开”
3(在主程序中)遍历所有点:memset(used,0),goto 2
bool dfs(int x)
{
for(int i=0,v;i<edge[x].size();i++)
{
if(!used[y=e[x][i]])
{
visit[v]=1;
if(!match[v] || dfs(match[v]))
{
match[v]=x;
return 1;
}
}
}
return 0;
}