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个,则按需补上没有要求的学生即可,然后输出编号。由于学生的“要求”具有传递性,所以用邻接矩阵表示某个学生想和另一个学生一组。深度优先遍历,建立一个数组用来表示某个学生是否被访问过。

#include <iostream>
#include <vector>
using namespace std;
bool matrix[48][48];
bool visited[48];
int n;
vector<vector<int> > teams;
vector<int> team;
void dfs(int current)
{
    team.push_back(current);
    visited[current] = true;
    for (int j = 0; j<n; j++)
    if (matrix[current][j] && !visited[j])
        dfs(j);
}
int main()
{
    int  m;
    cin >> n >> m;
    memset(matrix, false, sizeof(matrix));
    memset(visited, false, sizeof(visited));
    for (int j = 0; j<m; j++)
    {
        int a, b;
        cin >> a >> b;
        matrix[a - 1][b - 1] = matrix[b - 1][a - 1] = true;
    }
    vector<int> free;
    for (int j = 0; j<n; j++)
    {
        bool isfree = true;
        for (int k = 0; k<n; k++)
        {
            if (matrix[j][k])
                isfree = false;
        }
        if (isfree)
        {
            visited[j] = true;
            free.push_back(j);
        }
    }
    for (int j = 0; j<n; j++)
    if (!visited[j])
    {
        team.clear();
        dfs(j);
        if (team.size()>3)
        {
            cout << -1;
            return 0;
        }
        while (team.size()<3)
        {
            if (free.empty())
            {
                cout << -1;
                return 0;
            }
            team.push_back(free.back());
            free.pop_back();
        }
        teams.push_back(team);
    }
    if (teams.size()<n / 3)
    while (!free.empty())
    {
        team.clear();
        for (int j = 0; j<3; j++)
        {
            team.push_back(free.back());
            free.pop_back();
        }
        teams.push_back(team);
    }
    for (int j = 0; j<teams.size(); j++)
    {
        for (int k = 0; k<3; k++)
            cout << teams[j][k] + 1 << " ";
        cout << endl;
    }
    return 0;
}


你可能感兴趣的:(Codeforces Round #181 (Div. 2))