CodeForces 688C-NP-Hard Problem

题意:
  给你一个无向图,判断是否能够构成一个二分图,如果能的话,输出二分图左边的集合和右边的集合

分析:
    先给每一个顶点的color初始化-1,表示没有被染色,用vector数组v[a],表示元素a所相连的全部元素,然后枚举每一个顶点,发现没有被染色,就对它进行染色,先把顶点染成0,然后

再将染成颜色为0的vector加入当前元素,在枚举与这个元素相连的元素,假设颜色是c的话,相连的就染成c^1,它会把0变成1,1变成0;如果二分图左边是0,右边是1,则表示它已被染色直

接return,发现染色的颜色与该染的颜色不符合,就不能构成二分图了,ok=false.

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 
 7 using namespace std;
 8 
 9 const int maxn = 100000 + 10;
10 vector<int>g[maxn],v[2];
11 bool ok = true;
12 int color[maxn];
13 
14 void dfs(int k,int c)
15 {
16     if(!ok) //该顶点已被染色
17         return ;
18     if (color[k] != -1)
19     {
20         if (color[k] != c)  //发现染色的颜色与该染的颜色不符合,就不能构成二分图了,ok=false
21             ok = false;
22         return;
23     }
24     color[k] = c;
25     v[c].push_back(k);  //将已被染色的元素加入数组v中
26     int len = g[k].size();
27     for (int i = 0; i < len; i++)   //枚举与这个元素相连的元素
28         dfs(g[k][i],c^1); // 0 -> 1,, 1 -> 0;
29 }
30 
31 void print(vector<int> & t)
32 {
33     int len = t.size();
34     printf("%d
",len);
35     for (int i = 0; i < len; ++i)
36     {
37         if(i)
38             printf(" ");
39         printf("%d", t[i]);
40     }
41     printf("
");
42 }
43 
44 int main()
45 {
46     int n,  m;
47     while(scanf("%d%d", &n,&m)==2)
48     {
49         for(int i = 0; i < m; i++)
50         {
51             int u,w;
52             scanf("%d%d", &u, &w);
53             g[u].push_back(w);
54             g[w].push_back(u);
55         }
56         memset(color, -1, sizeof(color)); //初始化-1表示没被染色
57         for(int i = 1; i <= n; i++)
58         {
59             if (color[i] == -1) //对所有未染色的顶点染色
60                 dfs(i,0);
61         }
62         if(!ok)
63             printf("-1
");
64         else
65             for(int i = 0; i < 2; i++)
66                 print(v[i]);
67     }
68     return 0;
69 }
原文地址:https://www.cnblogs.com/xl1164191281/p/5669909.html