您的位置:首页 > 其它

染色法判断是否是二分图 hdu2444

2014-09-30 17:19 330 查看
用染色法判断二分图是这样进行的,随便选择一个点,

1.把它染成黑色,然后将它相邻的点染成白色,然后入队列

2.出队列,与这个点相邻的点染成相反的颜色

根据二分图的特性,相同集合内的点颜色是相同的,即



但是如果这个图不是二分图,那么就会这样



把与1相邻的点2,3染成白色,然后入队列,然后2出队列,要把与2相邻的点2,3染成黑色,但是都染过了,所以不用染色

但是3的颜色应该与2相反(如果是二分图的话),可是没有相反,所以就不是二分图

#include <stdio.h>
#include <queue>
#include <string.h>
using namespace std;
const int N = 300;
struct Edge
{
int v,next;
}g[N*N];
int first[N*N];
int color[N*N];
int cy
;
bool vis
;
int e;
int n,m;
bool is_ ;
void addEdge(int a, int b)
{
g[e].v = b;
g[e].next =first[a];
first[a] = e++;
}
bool bfs(int cur)//染色法,判断是否是二分图
{//时间复杂度   邻居矩阵O(n*n)   邻接表 O(n+e)
queue<int> q;
q.push(cur);
color[cur] = 1;
while(!q.empty())
{
cur = q.front();q.pop();
for(int i=first[cur]; i!=-1; i=g[i].next)
{
int v = g[i].v;
if(color[v] == -1)
{
color[v] = 1 - color[cur];
q.push(v);
}

if(color[v] == color[cur])
return false;
}
}
return true;
}
void dfs_color(int cur)
{
for(int i=first[cur]; i!=-1; i=g[i].next)
{
int v = g[i].v;
if(color[v] == -1)
{
color[v] = 1 - color[cur];
dfs_color(v);
}
else if(color[v] == color[cur])
is_ = false;

}

}
bool dfs(int cur)
{
for(int i=first[cur]; i!=-1; i=g[i].next)
{
int v = g[i].v;
if(!vis[v])
{
vis[v] = true;
if(cy[v]==-1 || dfs(cy[v]))
{
cy[v] = cur;
return true;
}
}
}
return false;
}
int Match()
{
int ans = 0;
memset(cy, -1, sizeof(cy));
for(int i=1; i<=n; ++i)
{
memset(vis, 0, sizeof(vis));
ans += dfs(i);
}
return ans;
}
int main()
{
freopen("in.txt","r",stdin);
int a,b,i;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(first, -1, sizeof(first));
e = 0;
for(i=0; i<m; ++i)
{
scanf("%d%d",&a,&b);
addEdge(a,b);
addEdge(b,a);
}
is_ = true;
memset(color, -1, sizeof(color));
for(i=1; i<=n; ++i)
{
if(color[i] == -1)
{
color[i] = 1;
dfs_color(i);
}
}
if(!is_)
puts("No");
else
{
printf("%d\n",Match()/2);//没有把集合x,y分开,所以相当有2个最大匹配
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: