📜  安排所有考试所需的最少天数

📅  最后修改于: 2021-10-25 03:25:44             🧑  作者: Mango

给定一个由N 个节点组成的图,其中每个节点代表一次考试和一个二维数组Edges[][2] ,使得每对考试(Edges[i][0], Edges[i][1])表示它们之间的边缘,任务是找到安排所有考试所需的最少天数,这样通过边缘连接的两个考试不会安排在同一天。

例子:

方法:给定的问题可以通过使用图着色的概念来解决。请按照以下步骤解决给定的问题:

  • 从图中给定的 Edges[][] 创建一个邻接矩阵。
  • 初始化一个成对向量,比如vdegree[] ,它存储每个节点与节点的度数。
  • 计算每个顶点的度数并将其存储在数组vdegree[] 中
  • 按度数降序排列vdegree[]中的所有顶点。
  • 初始化两个 数组,比如color[]coloured[]来存储用于着色顶点的颜色以及顶点是否已着色。
  • 初始化两个变量,例如numvcK0 ,以跟踪分配给每个节点的着色顶点数量和颜色编号。
  • 使用变量i在范围[0, V] 上迭代并执行以下步骤:
    • 如果 numvc的值与V相同,则在所有顶点都着色时跳出循环。
    • 如果当前顶点是彩色的,则继续迭代。
    • 如果顶点没有着色,则使用颜色K顶点着色为 coloured[vdegree[i]] = color[K]并增加numvc的值。
    • 迭代范围[0, V] ,如果当前顶点未着色且与节点i不相邻,则使用颜色K为当前节点着色并增加numvc的值。
    • 将 K的值增加1
  • 按递增顺序对数组 coloured[] 进行排序。
  • 完成上述步骤后,将数组 coloured[] 中存在的唯一元素数的值打印为最小天数。

下面是上述方法的实现:

C++14
// C++ program for the above approach
  
#include 
using namespace std;
  
// Comparator function to sort the
// vector of pairs in decreasing order
bool compare(pair a,
             pair b)
{
    // If the first values are the same
    if (a.first == b.first) {
        return (a.second < b.second);
    }
  
    // Otherwise
    else {
        return (a.first > b.first);
    }
}
  
// Function to add an undirected
// edge between any pair of nodes
void addEdge(vector >& adj,
             int u, int v)
{
    adj[u][v] = 1;
    adj[v][u] = 1;
}
  
// Function to find the minimum number
// of days to schedule all the exams
int minimumDays(int V, int Edges[][2],
                int E)
{
    // Stores the adjacency list of
    // the given graph
    vector > adj(
        V, vector(V, 0));
  
    // Iterate over the edges
    for (int i = 0; i < E; i++) {
  
        int u = Edges[i][0];
        int v = Edges[i][1];
  
        // Add the edges between the
        // nodes u and v
        addEdge(adj, u, v);
    }
  
    // Initialize a vector of pair that
    // stores { degree, vertex }
    vector > vdegree(V);
  
    for (int i = 0; i < V; i++) {
  
        // Degree of the node
        int degree = 0;
        vdegree[i].second = i;
  
        for (int j = 0; j < V; j++) {
            if (adj[i][j] != 0) {
  
                // Increment the degree
                degree++;
            }
        }
  
        // Update the degree of the
        // current node
        vdegree[i].first = degree;
    }
  
    // Sort to arrange all vertices
    // in descending order of degree
    sort(vdegree.begin(),
         vdegree.end(), compare);
  
    // Stores the vertices according
    // to degree in descending order
    int vorder[V];
  
    for (int i = 0; i < V; i++) {
        vorder[i] = vdegree[i].second;
    }
  
    // Stores the color of the all
    // the nodes
    int color[V];
  
    for (int i = 0; i < V; i++) {
        color[i] = i + 1;
    }
  
    int colored[V];
  
    // Initialize all vertices with
    // an invalid color 0
    memset(colored, 0, sizeof(colored));
  
    // Keeps the track of number of
    // vertices colored
    int numvc = 0;
  
    // Track the different color
    // assigned
    int k = 0;
  
    for (int i = 0; i < V; i++) {
  
        // If all vertices are colored
        // then exit from the for loop
        if (numvc == V) {
            break;
        }
  
        // If vertex is already
        // colored, then continue
        if (colored[vorder[i]] != 0) {
            continue;
        }
  
        // If vertex not colored
        else {
  
            colored[vorder[i]] = color[k];
  
            // After coloring increase
            // the count of colored
            // vertex by 1
            numvc++;
  
            for (int j = 0; j < V; j++) {
  
                // If the current node
                // and its adjacent are
                // not colored
                if (colored[j] == 0
                    && adj[vorder[i]][j] == 0) {
  
                    colored[j] = color[k];
  
                    // Increment the count
                    numvc++;
                }
            }
  
            // Increment k
            k++;
        }
    }
  
    // Sort the array
    sort(colored, colored + V);
  
    // Count of unique colors
    int unique_color = 1;
  
    // Count the number of unique
    // colors
    for (int i = 1; i < V; i++) {
  
        if (colored[i]
            != colored[i - 1]) {
            unique_color++;
        }
    }
  
    // Return the number of days
    // to sechedule an exam
    return unique_color;
}
  
// Driver Code
int main()
{
    int V = 7, E = 12;
    int Edges[][2]
        = { { 0, 1 }, { 0, 3 }, { 0, 4 }, { 0, 6 }, { 1, 2 }, { 1, 4 }, { 1, 6 }, { 2, 5 }, { 2, 6 }, { 3, 4 }, { 3, 5 }, { 4, 5 } };
    cout << minimumDays(V, Edges, E);
  
    return 0;
}


输出:
3

时间复杂度: O(N 2 )
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。