题意: 判断给出的条件能否构成二分图,不能则输出-1
,可以的话还要输出染色以后的两个集合(输出其中一种正确的答案即可)。
题解: 用dfs给点染色。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1e5 + 10;
int n, m, x, y, cnt, ans;
int head[maxn], color[maxn];
struct node{ int v, next;} e[2 * maxn];
void add(int u, int v){ //链式前向星存图
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt++;
}
bool dfs(int u, int c){ //u为端点编号,c为染色(1或-1)
color[u] = c; //染色
for (int i = head[u]; ~i; i=e[i].next){
int v = e[i].v; /另一端点编号
if(color[v] == c) return false; //两端点同色,不能构成二分图
if(!color[v] && !dfs(v, -c)) return false; //另一端点未染色,但是染上-c之后依然不能构成二分图
}
return true;
}
int main(){
memset(head, -1, sizeof head);
scanf("%d%d", &n, &m);
while(m--){
scanf("%d%d", &x, &y);
add(x, y), add(y, x);
}
for (int i = 1; i <= n; i++)
if(head[i]!=-1 && !color[i])
if (!dfs(i, 1)){ printf("-1\n"); return 0;}
for (int i = 1; i <= n; i++) if (color[i] == 1) ans++;
printf("%d\n", ans);
for (int i = 1; i <= n; i++) if (color[i] == 1) printf("%d ", i);
printf("%d\n", n - ans);
for (int i = 1; i <= n; i++) if (color[i] != 1) printf("%d ", i);
return 0;
}