标签:
题意:已知有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 }
Codeforces Round #181 (Div. 2)
标签:
原文地址:http://www.cnblogs.com/jzwong/p/4320608.html