二分图的判断和二分图最大匹配模板
2015-05-11 13:22
393 查看
二分图的判定:是否能够将点集分成两个集合,使得对于每条边都有该边的一个点在一个集合,另一个在另一个集合。
hihocoder 1121 二分图判定
题目链接:hihocoder 1121
们的问题就转化为判定是否存在一个合理的染色方案,使得我们所建立的无向图满足每一条边两端的顶点颜色都不相同。
那么,我们不妨将所有的点初始为未染色的状态。随机选择一个点,将其染成白色。再以它为起点,将所有相邻的点染成黑色。再以这些黑色的点为起点,将所有与其相邻未染色的点染成白色。不断重复直到整个图都染色完成。(如下图)
在染色的过程中,我们应该怎样发现错误的记录呢?相信你一定发现了吧。对于一个已经染色的点,如果存在一个与它相邻的已染色点和它的颜色相同,那么就一定存在一条错误的记录。(如上图的4,5节点)
到此我们就得到了整个图的算法:
选取一个未染色的点u进行染色
遍历u的相邻节点v:若v未染色,则染色成与u不同的颜色,并对v重复第2步;若v已经染色,如果 u和v颜色相同,判定不可行退出遍历。
若所有节点均已染色,则判定可行。
分析:按照提示写出判断
二分图最大匹配的模板:
DFS实现:(邻接表 用vector数组实现)
BFS实现:(邻接矩阵 用二维数组实现)
hihocoder 1121 二分图判定
题目链接:hihocoder 1121
们的问题就转化为判定是否存在一个合理的染色方案,使得我们所建立的无向图满足每一条边两端的顶点颜色都不相同。
那么,我们不妨将所有的点初始为未染色的状态。随机选择一个点,将其染成白色。再以它为起点,将所有相邻的点染成黑色。再以这些黑色的点为起点,将所有与其相邻未染色的点染成白色。不断重复直到整个图都染色完成。(如下图)
在染色的过程中,我们应该怎样发现错误的记录呢?相信你一定发现了吧。对于一个已经染色的点,如果存在一个与它相邻的已染色点和它的颜色相同,那么就一定存在一条错误的记录。(如上图的4,5节点)
到此我们就得到了整个图的算法:
选取一个未染色的点u进行染色
遍历u的相邻节点v:若v未染色,则染色成与u不同的颜色,并对v重复第2步;若v已经染色,如果 u和v颜色相同,判定不可行退出遍历。
若所有节点均已染色,则判定可行。
分析:按照提示写出判断
#include<cstdio> #include<vector> #include<map> #include<queue> #include<string.h> #include<iostream> #include<cmath> #include<algorithm> using namespace std; int vis[10005]; vector<int> vt[10005]; queue<int> qt; int n,flag,t; int main() { int cas,i,m,a,b; scanf("%d",&cas); while(cas--) { scanf("%d %d",&n,&m); for(i=0;i<=n;i++) vt[i].clear(); while(!qt.empty()) qt.pop(); for(i=0;i<m;i++) { scanf("%d %d",&a,&b); vt[a].push_back(b); } if(n==1) { printf("Correct\n"); continue; } memset(vis,0,sizeof(vis)); vis[a]=1; flag=0; for(i=0;i<vt[a].size();i++) { vis[vt[a][i]]=2; qt.push(vt[a][i]); } while(!qt.empty()) { t=qt.front(); qt.pop(); for(i=0;i<vt[t].size();i++) { int tt=vt[t][i]; if( vis[tt]==0) { if(vis[t]==1) vis[tt]=2; else vis[tt]=1; qt.push(tt); } else if( vis[tt]==vis[t]) { flag=1; break; } } } if(flag==1) puts("Wrong"); else puts("Correct"); } }
二分图最大匹配的模板:
DFS实现:(邻接表 用vector数组实现)
const int maxn=512; bool used[maxn]; vector<int>g[maxn]; int L,R; int x[maxn],y[maxn]; bool SearchPath(int u) { int Size=g[u].size(),v; for(int i=0;i<Size;i++) { v=g[u][i]; if(!used[v]) { used[v] = true; if(y[v] == -1 || SearchPath(y[v])) { y[v]=u; x[u]=v; return true; } } } return false; } int MaxMatch() { int ret=0; memset(x,-1,sizeof(x)); memset(y,-1,sizeof(y)); for(int u=1;u<=L;u++) { if(x[u]==-1) { memset(used,false,sizeof(used)); if(SearchPath(u)) ret++; } } return ret; }
BFS实现:(邻接矩阵 用二维数组实现)
const int maxn=512; int g[maxn][maxn]; int L,R; int x[maxn],y[maxn]; int Q[maxn]; //模拟队列 int pre[maxn]; int MaxMatch() { int res=0,temp; memset(x,-1,sizeof(x)); memset(y,-1,sizeof(y)); for(int i=1;i<=L;i++) { if(x[i]==-1) { int cur=0,tail=0; for(int j=1;j<=R;j++) { if(g[i][j]) pre[j]=-1,Q[tail++]=j; else pre[j]=-2; } //BFS while(cur<tail) { temp=Q[cur]; if(y[temp]==-1) break; cur++; for(int j=1;j<=R;j++) { if(pre[j]==-2&&g[y[temp]][j]) { pre[j]=temp; Q[tail++]=j; } } } //end of BFS if(cur==tail) //没有找到交错轨 continue; while(pre[temp]>-1) //更改交错轨上匹配状态 { x[ y[pre[temp]] ]=temp; y[temp]=y[pre[temp]]; temp=pre[temp]; } y[temp]=i;x[i]=temp; res++; } } return res; }
相关文章推荐
- HDU 2444 The Accomodation of Students(最大二分匹配(匈牙利算法)+二分图判断->模板题目)
- 求二分图最大匹配——匈牙利算法模板。
- hdoj 2063 过山车 (二分图-最大匹配模板)
- Dinic 二分图最大匹配最大流解法(来自lixiyi学姐的模板
- SPOJ 4206 Fast Maximum Matching (二分图最大匹配 Hopcroft-Carp 算法 模板)
- hdu 2444 The Accomodation of Students(最大匹配 + 二分图判断)
- UOJ#80 二分图最大权匹配 [模板题]
- (模板题)poj 3041 Asteroids(二分图的最大匹配匈牙利算法)
- KM算法 求二分图最大权值的完美匹配 【模板 记录】
- hdu 2444 The Accomodation of Students (判断二分图,二分图最大匹配)
- 【二分图判断 && 二分图最大匹配】HDU - 2444 The Accomodation of Students
- 二分图最大权匹配 、 最小权匹配 模板
- [HDU]2444 The Accomodation of Students二分图最大流匹配模板
- HDU 2063 过山车 【二分图最大匹配(匈牙利模板)】
- 匈牙利算法求二分图的最大匹配/匈牙利算法模板
- hdu 2444 The Accomodation of Students(二分图判断,二分图最大匹配)
- hdu 2444(二分图的判断以及求最大匹配)
- POJ3041 二分图(性质)最小点覆盖等于最大匹配数(匈牙利模板题)
- hdu2444 The Accomodation of Students (二分图判断+最大匹配)
- The Accomodation of Students HDU - 2444(最大二分匹配+染色法判断二分图)