ACM模板判断二分图+二分图最大匹配
Posted nefu_ljw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM模板判断二分图+二分图最大匹配相关的知识,希望对你有一定的参考价值。
POJ 2492 A Bug’s Life
判断无向图是否为二分图,注意图可能不连通。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
const int N=1e4+10;
vector<int> g[N];
int color[N]; // 记录点的染色为0或1,初始时未染色则为-1
bool dfs(int u,int now_color) // 当前点为u,当前染色为now_color(取值0或1)
{
color[u]=now_color;
for(int i=0;i<g[u].size();i++) // 邻接点v
{
int v=g[u][i];
if(color[v]==color[u]) // 与邻接点颜色相同
return 0; // 不为二分图,返回0
if(color[v]==-1&&!dfs(v,color[u]^1)) // 邻接点未染色则继续dfs递归,判断其能否染色
return 0; // 染色失败,dfs返回本层结果为0,本层再向上返回0
}
return 1;
}
bool solve(int n)
{
for(int i=1;i<=n;i++) // 可能不是连通图,所以dfs所有点
if(color[i]==-1&&!dfs(i,0))return 0; // 若i点未被染色,则dfs
return 1;
}
int main()
{
ios::sync_with_stdio(false);
int T,cas=0;cin>>T;
while(T--)
{
int n,m,x,y;
cin>>n>>m;
for(int i=1;i<=n;i++)
g[i].clear();
memset(color,-1,sizeof(color));
while(m--)
{
cin>>x>>y;
g[x].push_back(y);
g[y].push_back(x);
}
printf("Scenario #%d:\\n",++cas);
if(solve(n))printf("No suspicious bugs found!\\n\\n");
else printf("Suspicious bugs found!\\n\\n");
}
return 0;
}
洛谷 P3386 【模板】二分图最大匹配
#include <bits/stdc++.h>
using namespace std;
const int N=1e4+10,E=5e4+10;
int cnt,head[N];
struct edge
{
int to,next;
}e[E<<1];
void add(int x,int y)
{
e[cnt].to=y;
e[cnt].next=head[x];
head[x]=cnt++;
}
bool vis[N]; // vis[v]=1表示左部点尝试找配对点过程中v已被预定匹配
int match[N]; // match[v]=u表示右部点v的配对点是左部点u(初始未匹配,值为0)
bool dfs(int u) // 左部点u,dfs尝试找到它的配对点
{
for(int i=head[u];~i;i=e[i].next)
{
int v=e[i].to; // 可以与u相连的右部点v
if(vis[v])continue; // 左部点u尝试找配对点过程中v已被预定匹配
vis[v]=1;
if(!match[v]||dfs(match[v]))
// 1.如果v还没匹配,直接match[v]=u让它匹配上,不再递归直接返回1
// 2.如果v已被匹配,那么继续dfs递归,尝试能否让现在v的配对点match[v]换一个配对点,
// 这里可能多次递归,一直到最后一个点看它能否匹配上,再向上返回0或1
{
match[v]=u;
return 1; // 匹配成功
}
}
return 0; // 以上尝试均失败,返回0
}
int main()
{
ios::sync_with_stdio(false);
memset(head,-1,sizeof(head));
int n,m,e,x,y;
cin>>n>>m>>e;
while(e--)
{
cin>>x>>y;
add(x,y); // 只需单向边,因为之后只遍历右部向左部连的边
}
int sum=0;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis)); // 注意每个左部点匹配之前都要清除上次右部点被预定的标记
if(dfs(i))sum++;
}
printf("%d\\n",sum);
return 0;
}
以上是关于ACM模板判断二分图+二分图最大匹配的主要内容,如果未能解决你的问题,请参考以下文章