二分图 学习笔记
相关链接
题单:https://www.luogu.com.cn/training/79728
二分图的判定
如果一张无向图,可以将图中的点分成两个集合
如图即是一个二分图,
二分图的性质有这些:
- 对二分图进行染色,相邻的点不可以染同色,用两个颜色即可覆盖这个图。
- 二分图没有长度为奇数的环,因为每一次都会从一个一个集合到另一个集合。
我们可以运用这些性质来进行判定。每次从一个未染色点出发,如果有颜色而且是同色,那么不是二分图,否则给相邻的点染上反色,并继续向下搜索。
关联题目:P1330 封锁阳光大学
代码
#define maxn 10050
int n,m;
vector<int>G[maxn];
int col[maxn],bel[maxn];
int sum[3][maxn];
bool flg=0;
bool dfs(int now,int c,int nth) {
col[now]=c; bel[now]=nth;
for(auto nxt:G[now]) {
if(col[nxt]==c) return 0;
if(!col[nxt]&&!dfs(nxt,3-c,nth)) return 0;
}
return 1;
}
signed main() {
in2(n,m);
For(i,1,m) {
int a,b;
in2(a,b);
pb(G[a],b);
pb(G[b],a);
}
int tot=0;
For(i,1,n)
if(!col[i])
if(!dfs(i,1,++tot))
return cout<<"Impossible",0;
int cnt=0;
For(i,1,n) sum[col[i]][bel[i]]++;
For(i,1,tot) cnt+=min(sum[1][i],sum[2][i]);
cout<<cnt;
}
二分图最大匹配
匹配或是独立边集是一张图中不具有公共端点的边的集合。
左部的点集
由于最大匹配的边数是确定的,所以我们可以随便选一个起点。
时间复杂度
关联题目:P3386 【模板】二分图最大匹配
代码
#define maxn 510
int n,m,e,ans,G[maxn][maxn],to[maxn],u,v;
bool vis[maxn];
bool dfs(int now) {
For(i,1,m) if(G[now][i]&&!vis[i]) {
vis[i]=1;
if(!to[i]||dfs(to[i])) return to[i]=now,1;
}
return 0;
}
signed main() {
in3(n,m,e);
For(i,1,e) in2(u,v),G[u][v]=1;
For(i,1,n) m0(vis),ans+=dfs(i);
cout<<ans;
}
本文来自博客园,作者:coding_goat_qwq,转载请注明原文链接:https://www.cnblogs.com/CodingGoat/p/18458392
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现