链接:
http://acm.timus.ru/problem.aspx?space=1&num=1106
描述:有n(n<=100)个人,每个人有一个或多个朋友(朋友关系是相互的)。将其分成两组,使每一组都有朋友在另一个组。
还有一种方法差不多,看着像dfs实际不是,本题只需要对每个结点的邻接点染色就行,可以不用递归。
描述:有n(n<=100)个人,每个人有一个或多个朋友(朋友关系是相互的)。将其分成两组,使每一组都有朋友在另一个组。
思路:大意就是求一个子图使其是二分图。直接用dfs染色。 实际上不是二分图,因为本题每个子集里边可以有边相连,只要满足题目给的条件就行了。比二分图简单了一些。
//g++ 4.7.2
- #include <cstdio>
- #include <iostream>
- #include <cstring>
- #include <vector>
- using namespace std;
- const int M = 100 + 10;
- int color[M], vis[M]; //color[i]表示结点i的颜色,1表示黑色,2白色
- vector<int> G[M];
- void dfs(int u)
- {
- vis[u] = 1;
- for (int i = 0; i < G[u].size(); ++i)
- {
- int v = G[u][i];
- if (!vis[v])
- {
- color[v] = 3 - color[u];
- dfs(v);
- }
- }
- }
- int main()
- {
- int n, t;
- scanf("%d", &n);
- for (int i = 1; i <= n; ++i)
- while (scanf("%d", &t) && t)
- {
- G[i].push_back(t);
- }
- memset(vis, 0, sizeof(vis));
- memset(color, 0, sizeof(color));
- for (int i = 1; i <= n; ++i)
- if (!vis[i])
- {
- color[i]=1; //每个新连通分量起始点都要设置为1
- dfs(i);
- }
- int sum = 0;
- for (int i = 1; i <= n; ++i)
- if (color[i] == 1)
- ++sum;
- printf("%d\n", sum);
- for (int i = 1; i <= n; ++i)
- if (color[i] == 1)
- printf("%d ", i);
- return 0;
- }
- #include <cstdio>
- #include <iostream>
- #include <cstring>
- #include <vector>
- using namespace std;
- const int M = 100 + 10;
- int color[M], vis[M];
- vector<int> G[M];
- void coloring(int u)
- {
- vis[u] = 1;
- color[u] = 1;
- for (int i = 0; i < G[u].size(); ++i)
- {
- int v = G[u][i];
- if (!vis[v])
- color[v] = 3 - color[u];
- vis[v] = 1;
- }
- }
- int main()
- {
- int n, t;
- scanf("%d", &n);
- for (int i = 1; i <= n; ++i)
- while (scanf("%d", &t) && t)
- {
- G[i].push_back(t);
- }
- memset(vis, 0, sizeof(vis));
- memset(color, 0, sizeof(color));
- for (int i = 1; i <= n; ++i)
- if (!vis[i])
- coloring(i);
- int sum = 0;
- for (int i = 1; i <= n; ++i)
- if (color[i] == 1)
- ++sum;
- printf("%d\n", sum);
- for (int i = 1; i <= n; ++i)
- if (color[i] == 1)
- printf("%d ", i);
- return 0;
- }