传送门:Codeforces Round #360 (Div. 2) – C. NP-Hard Problem
题目大意
给你一个无向图,判断是否能够构成一个二分图,如果能的话,输出二分图左边的集合和右边的集合。
解题思路
比较简单的二分图对每一个没有染色的节点进行DFS染色,如果已经连接的节点已经染色了,如果相邻的节点已经染色,并且颜色是相同的就是不能构成二分图!
AC代码
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN = 5e6+5;
int head[MAXN],edgeCnt,color[MAXN];
bool flag;
vector<int>g[3];
struct Edge{
int v,nxt;
}E[MAXN];
void initEdge()
{
edgeCnt = 0;
flag = true;
memset(color,-1,sizeof color);
memset(head,-1,sizeof head);
}
void addEdge(int u,int v)
{
E[edgeCnt].v = v;
E[edgeCnt].nxt = head[u];
head[u] = edgeCnt++;
}
void dfs(int k,int c)
{
if(!flag) return ;
if(color[k]!=-1)
{
if(color[k]!=c) flag = false;
return ;
}
color[k] = c;
g[c].push_back(k);
for(int i=head[k];~i;i=E[i].nxt)
{
int v = E[i].v;
dfs(v,c^1);
}
}
int main()
{
int N,M;
int u,v;
while(~scanf("%d%d",&N,&M))
{
initEdge();
for(int i=0;i<M;i++)
{
scanf("%d%d",&u,&v);
addEdge(u,v);
addEdge(v,u);
}
for(int i=1;i<=N;i++)
if(color[i] == -1)dfs(i,0);
if(!flag){
puts("-1");
continue;
}
for(int i=0;i<2;i++)
{
printf("%d\n",g[i].size());
for(int j=0;j<g[i].size();j++)
if(j==(g[i].size()-1))printf("%d ",g[i][j]);
else printf("%d\n",g[i][j]);
}
}
return 0;
}