题意:
给你一个无向图,判断是否能够构成一个二分图,如果能的话,输出二分图左边的集合和右边的集合
分析:
先给每一个顶点的color初始化-1,表示没有被染色,用vector数组v[a],表示元素a所相连的全部元素,然后枚举每一个顶点,发现没有被染色,就对它进行染色,先把顶点染成0,然后
再将染成颜色为0的vector加入当前元素,在枚举与这个元素相连的元素,假设颜色是c的话,相连的就染成c^1,它会把0变成1,1变成0;如果二分图左边是0,右边是1,则表示它已被染色直
接return,发现染色的颜色与该染的颜色不符合,就不能构成二分图了,ok=false.
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector> using namespace std; const int maxn = + ;
vector<int>g[maxn],v[];
bool ok = true;
int color[maxn]; void dfs(int k,int c)
{
if(!ok) //该顶点已被染色
return ;
if (color[k] != -)
{
if (color[k] != c) //发现染色的颜色与该染的颜色不符合,就不能构成二分图了,ok=false
ok = false;
return;
}
color[k] = c;
v[c].push_back(k); //将已被染色的元素加入数组v中
int len = g[k].size();
for (int i = ; i < len; i++) //枚举与这个元素相连的元素
dfs(g[k][i],c^); // 0 -> 1,, 1 -> 0;
} void print(vector<int> & t)
{
int len = t.size();
printf("%d\n",len);
for (int i = ; i < len; ++i)
{
if(i)
printf(" ");
printf("%d", t[i]);
}
printf("\n");
} int main()
{
int n, m;
while(scanf("%d%d", &n,&m)==)
{
for(int i = ; i < m; i++)
{
int u,w;
scanf("%d%d", &u, &w);
g[u].push_back(w);
g[w].push_back(u);
}
memset(color, -, sizeof(color)); //初始化-1表示没被染色
for(int i = ; i <= n; i++)
{
if (color[i] == -) //对所有未染色的顶点染色
dfs(i,);
}
if(!ok)
printf("-1\n");
else
for(int i = ; i < ; i++)
print(v[i]);
}
return ;
}