标签:
题意:
给你一个无向图,判断是否能够构成一个二分图,如果能的话,输出二分图左边的集合和右边的集合
分析:
先给每一个顶点的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\n",len);
35 for (int i = 0; i < len; ++i)
36 {
37 if(i)
38 printf(" ");
39 printf("%d", t[i]);
40 }
41 printf("\n");
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\n");
64 else
65 for(int i = 0; i < 2; i++)
66 print(v[i]);
67 }
68 return 0;
69 }
CodeForces 688C-NP-Hard Problem
标签:
原文地址:http://www.cnblogs.com/xl1164191281/p/5669909.html