1.二分图:
二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
百科:http://baike.baidu.com/link?url=iImhnK5sz4CE4b6C4ml0FrZjoLq076yjkRNTDvw0NstJTwsMa1MVp5QjIcEPsMoB
2.二分图的判断方法:
黑白染色法:
开始对任意一未染色的顶点染色,之后判断其相邻的顶点中,若未染色则将其染上和该顶点不同的颜色,若已经染色且颜色和该顶点的颜色相同则说明不是二分图,若颜色不同则继续判断。
DFS:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int NM=205;
int a[NM][NM],col[NM],n;
int Color(int x)
{
int i,t;
for(i=1;i<=n;i++)
{
if(a[x][i])
{
if(col[i]==col[x]) return false;
if(col[i]==-1)
{
col[i]=1-col[x];
t=Color(i);
if(!t) return false;
}
}
}
return true;
}
int main()
{
int num,x,y,i,ans;
bool f;
while(scanf("%d%d",&n,&num)!=EOF)
{
memset(a,0,sizeof(a));
for(i=0;i<num;i++)
{
scanf("%d%d",&x,&y);
a[x][y]=a[y][x]=1;
}
f=0;
memset(col,-1,sizeof(col));
for(i=1;i<=n;i++)
{
if(col[i]!=-1) continue;
col[i]=1;
if(!Color(i))
{
f=1;
printf("No\n");
break;
}
}
if(!f) printf("Yes\n");
}
return 0;
}
int Color()
{
int i,j,t;
memset(col,-1,sizeof(col));
for(i=1;i<=n;i++) //遍历所有点,以防二分图不连通导致错误
{
if(col[i]!=-1) continue;
col[i]=1;
queue<int>q1;
q1.push(i);
while(!q1.empty())
{
t=q1.front();q1.pop();
for(j=1;j<=n;j++)
if(a[t][j])
{
if(col[t]==col[j]) return false;
if(col[j]==-1)
{
col[j]=1-col[t];
q1.push(j);
}
}
}
}
return true;
}
3.二分图匹配分类:
1.最大匹配
2.最小顶点覆盖(=最大匹配(无向图/2))
3.最大独立集(节点数 - 二分图最大匹配/2(关系是双向的))
4.DAG图的最小路径覆盖(节点数 - 最大匹配数)