Codeforces Round #181 (Div. 2)

B. Coach

题意:已知有n个学生,编号从1到n,其中n是3的倍数,老师需要把这n个学生分成3人的小组。若第i个学生要和第j个学生一组,那么第j个学生一定也想和第i个学生一组(当然第i或者第j个学生也可能和其他第k个学生一组)。老师分组的时候需要满足学生的要求。若能按要求实现分组,则输出各组学生的编号;否则输出-1;

分析:首先需要找出有要求的学生进行深度优先遍历,若从某一个学生开始遍历长度大于3即按学生的要求编成的某一组的学生个数超过3个,则输出-1;若正好3个,则依次输出这3个学生的编号;若小于3个,则按需补上没有要求的学生即可,然后输出编号。由于学生的“要求”具有传递性,所以用邻接矩阵表示某个学生想和另一个学生一组。深度优先遍历,建立一个数组用来表示某个学生是否被访问过。

 1 #include <iostream>
 2 #include <vector>
 3 using namespace std;
 4 bool matrix[48][48];
 5 bool visited[48];
 6 int n;
 7 vector<vector<int> > teams;
 8 vector<int> team;
 9 void dfs(int current)
10 {
11     team.push_back(current);
12     visited[current] = true;
13     for (int j = 0; j<n; j++)
14     if (matrix[current][j] && !visited[j])
15         dfs(j);
16 }
17 int main()
18 {
19     int  m;
20     cin >> n >> m;
21     memset(matrix, false, sizeof(matrix));
22     memset(visited, false, sizeof(visited));
23     for (int j = 0; j<m; j++)
24     {
25         int a, b;
26         cin >> a >> b;
27         matrix[a - 1][b - 1] = matrix[b - 1][a - 1] = true;
28     }
29     vector<int> free;
30     for (int j = 0; j<n; j++)
31     {
32         bool isfree = true;
33         for (int k = 0; k<n; k++)
34         {
35             if (matrix[j][k])
36                 isfree = false;
37         }
38         if (isfree)
39         {
40             visited[j] = true;
41             free.push_back(j);
42         }
43     }
44     for (int j = 0; j<n; j++)
45     if (!visited[j])
46     {
47         team.clear();
48         dfs(j);
49         if (team.size()>3)
50         {
51             cout << -1;
52             return 0;
53         }
54         while (team.size()<3)
55         {
56             if (free.empty())
57             {
58                 cout << -1;
59                 return 0;
60             }
61             team.push_back(free.back());
62             free.pop_back();
63         }
64         teams.push_back(team);
65     }
66     if (teams.size()<n / 3)
67     while (!free.empty())
68     {
69         team.clear();
70         for (int j = 0; j<3; j++)
71         {
72             team.push_back(free.back());
73             free.pop_back();
74         }
75         teams.push_back(team);
76     }
77     for (int j = 0; j<teams.size(); j++)
78     {
79         for (int k = 0; k<3; k++)
80             cout << teams[j][k] + 1 << " ";
81         cout << endl;
82     }
83     return 0;
84 }
View Code
原文地址:https://www.cnblogs.com/jzwong/p/4320608.html