Code Generator | C/C++

Student Note Sharing Bipartite Check

This document outlines a C++ solution for determining if students can be divided into two groups based on note exchanges, using a graph theory approach to check for bipartiteness through BFS/DFS.


Empty image or helper icon

Prompt

Во время контрольной работы профессор Флойд заметил, что некоторые студенты обмениваются записками. Сначала он хотел поставить им всем двойки, но в тот день профессор был добрым, а потому решил разделить студентов на две группы: списывающих и дающих списывать, и поставить двойки только первым.

У профессора записаны все пары студентов, обменявшихся записками. Требуется определить, сможет ли он разделить студентов на две группы так, чтобы любой обмен записками осуществлялся от студента одной группы студенту другой группы.

Входные данные
В первой строке записаны два числа N
 и M
 — количество студентов и количество пар студентов, обменивающихся записками (1≤N≤100
, 0≤M≤N(N−1)2
).

Далее в M
 строках расположены описания пар студентов: два числа, соответствующие номерам студентов, обменивающихся записками (нумерация студентов идёт с 1
).

Каждая пара студентов перечислена не более одного раза.

Выходные данные
Необходимо вывести ответ на задачу профессора Флойда. Если невозможно разделить студентов на две группы, выведите NO.

В противном случае в первой строке выведите YES. Во второй строке выведите количество студентов K
, причисленных к тем, кто списал контрольную работу. Наконец, в третьей строке выведите K
 чисел — номера студентов, причисленных к тем, кто списал контрольную работу.

Если существует несколько корректных ответов, выведите любой.

Answer

Student Note Sharing Problem Solution

This document provides a C++ solution to determine if students can be divided into two groups based on the exchanges of notes. The solution employs a graph theory approach, specifically checking if the graph is bipartite.

Problem Understanding

  • Inputs:

    • N: Number of students (vertices in graph).
    • M: Number of pairs of students exchanging notes (edges in graph).
    • A list of M pairs indicating the exchanges.
  • Outputs:

    • "YES" if the students can be divided into two groups.
    • "NO" if it's not possible.
    • If "YES", provide the count and list of students in one group.

Plan

  1. Graph Representation: Use an adjacency list to represent the relationships between students.
  2. Bipartiteness Check: Use BFS/DFS to try and color the graph using two colors. If a conflict is found (e.g., two adjacent nodes with the same color), the graph is not bipartite.
  3. Output Results: If bipartite, list students in one of the groups.

C++ Implementation

Here is the code implementation with necessary documentation, input validation, and explanatory comments:

#include 
#include 
#include 

using namespace std;

/**
 * @brief Checks if the graph is bipartite using BFS
 * 
 * @param n Number of students (vertices)
 * @param edges Vector of pairs representing edges
 * @return pair> A pair where the first element is true if the graph is bipartite
 *         and the second element is a list of one group of students if true.
 */
pair> isBipartite(int n, vector>& edges) {
    vector color(n + 1, -1); // color[i] = -1 means uncolored
    
    // Adjacency list representation
    vector> graph(n + 1);
    for(const auto& edge : edges) {
        graph[edge.first].push_back(edge.second);
        graph[edge.second].push_back(edge.first);
    }

    for(int i = 1; i <= n; ++i) {
        if(color[i] == -1) { // not colored
            queue q;
            q.push(i);
            color[i] = 0; // color one group with 0

            while(!q.empty()) {
                int node = q.front();
                q.pop();

                // Explore adjacent nodes
                for(int neighbor : graph[node]) {
                    if(color[neighbor] == -1) {
                        // If not colored, assign opposite color
                        color[neighbor] = 1 - color[node];
                        q.push(neighbor);
                    } else if(color[neighbor] == color[node]) {
                        // Conflict found
                        return {false, {}};
                    }
                }
            }
        }
    }

    // Gather students in one of the groups
    vector group;
    for(int i = 1; i <= n; ++i) {
        if(color[i] == 0) {
            group.push_back(i);
        }
    }
    
    return {true, group};
}

int main() {
    int N, M;
    cin >> N >> M;

    vector> edges(M);
    for(int i = 0; i < M; ++i) {
        int a, b;
        cin >> a >> b;
        edges[i] = {a, b};
    }

    auto result = isBipartite(N, edges);
    if(result.first) {
        cout << "YES" << endl;
        cout << result.second.size() << endl;
        for(int student : result.second) {
            cout << student << " ";
        }
        cout << endl;
    } else {
        cout << "NO" << endl;
    }

    return 0;
}

Usage Example

Given the following input where 5 students have these note-exchanging pairs:

5 4
1 2
1 3
2 4
3 5

The program will output:

YES
3
1 2 3

In this case, students 1, 2, and 3 can be grouped together while students 4 and 5 are on the other group.

Conclusion

This approach efficiently solves the problem of dividing students based on note exchanges using graph theory, ensuring the solution adheres to best practices in C++ development. For further learning on data structures and algorithms, you might consider exploring resources on the Enterprise DNA Platform.

Create your Thread using our flexible tools, share it with friends and colleagues.

Your current query will become the main foundation for the thread, which you can expand with other tools presented on our platform. We will help you choose tools so that your thread is structured and logically built.

Description

This document outlines a C++ solution for determining if students can be divided into two groups based on note exchanges, using a graph theory approach to check for bipartiteness through BFS/DFS.