使形成环的边不具有相同颜色的最小所需颜色数


为了减少所需的颜色数量并避免边形成具有相同颜色的环,您可以使用图表着色方法。目标是将颜色映射到顶点,以便由边连接的两个相邻顶点不具有相同的颜色。通过识别图表中的环,我们能够保证构成环的边被分配不同的颜色。这需要使用深度优先搜索 (DFS) 或广度优先搜索 (BFS) 等策略遍历图表,并在必要时应用回溯以回溯并重新分配颜色。目标是找到满足条件并保证没有环具有相同颜色的边的所需的最少颜色数。

使用的方法

  • DFS

  • 贪婪着色算法

DFS

深度优先搜索 (DFS) 是一种图遍历算法,它通过沿着每个分支查看最远可能的顶点来回溯。它从选定的顶点开始,访问其相邻的未访问顶点,并递归地应用相同的过程。DFS 使用一个栈来跟踪要访问的顶点,以及一个已访问集来检查已访问的顶点。此算法有效地遍历图的深度,从而允许应用诸如路径查找、环检测和拓扑排序。通过有效地探索图,DFS 有效地查找未访问的顶点,使其成为理解和分析图结构的主要策略。

算法

  • 初始化边的空着色方案。

  • 创建一个已访问集来跟踪已访问的顶点。

  • 对于图中每个未访问的顶点 v

    • 将 v 标记为已访问。

      将第一个可用颜色分配给边连接 v 和其父节点(如果适用)。

      −递归地探索 v 的所有未访问邻居。

    • 如果邻居 u 已经被访问并且具有与 v 的边相同的颜色,则通过更改 v 的边的颜色进行回溯。

    • 如果邻居 u 未被访问,则将第一个可用颜色分配给连接 v 和 u 的边。

  • 如果所有边都成功着色且没有冲突,则返回着色方案。

  • 如果出现冲突并且不可能存在着色方案,则通过更改先前边的颜色进行回溯,并继续探索。

  • 重复步骤 3-5,直到找到有效的着色方案或所有可能的方案都已穷尽。

示例

#include <iostream>
#include <vector>
using namespace std;

const int numVertices = 5, numEdges = 7;

// Variable to store the graph
vector<pair<int, int>> adjacencyList[numEdges];

// To store whether a vertex is visited or not
int visited[numVertices];

// Boolean value to store whether the graph contains a cycle or not
bool hasCycle;

// Variable to store the color of the edges in the graph
int edgeColors[numEdges];

// Function to traverse the graph using DFS Traversal
void dfs(int vertex)
{
    visited[vertex] = 1;

    // Loop to iterate through all the edges from the source vertex
    for (auto edge : adjacencyList[vertex]) {
        int adjacentVertex = edge.first, edgeId = edge.second;

        // If the adjacent vertex is not visited
        if (visited[adjacentVertex] == 0) {
            dfs(adjacentVertex);
            edgeColors[edgeId] = 1;
        }

        // Condition to check cross and forward edges of the graph
        else if (visited[adjacentVertex] == 2) {
            edgeColors[edgeId] = 1;
        }

        // Presence of Back Edge
        else {
            edgeColors[edgeId] = 2;
            hasCycle = true;
        }
    }
    visited[vertex] = 2;
}

// Driver Code
int main()
{
    adjacencyList[0].push_back(make_pair(1, 0));
    adjacencyList[0].push_back(make_pair(2, 1));
    adjacencyList[1].push_back(make_pair(2, 2));
    adjacencyList[1].push_back(make_pair(3, 3));
    adjacencyList[2].push_back(make_pair(3, 4));
    adjacencyList[3].push_back(make_pair(4, 5));
    adjacencyList[4].push_back(make_pair(2, 6));

    // Loop to run DFS Traversal on vertices that are not visited
    for (int i = 0; i < numVertices; ++i) {
        if (visited[i] == 0) {
            dfs(i);
        }
    }
    cout << (hasCycle ? 2 : 1) << endl;

    // Loop to print the colors of the edges
    for (int i = 0; i < numEdges; ++i) {
        cout << edgeColors[i] << ' ';
    }
    return 0;
}

输出

2
1 1 1 1 1 1 2 

贪婪着色方法

贪婪着色方法是一种简单的算法,它对图的顶点进行着色,以确保没有相邻的顶点具有相同的颜色。它首先将第一个可用颜色分配给第一个顶点,然后继续按顺序对其余顶点进行着色。对于每个顶点,它选择其相邻顶点未使用的最小可用颜色。此方法确保有效的顶点着色,但可能不会始终产生所需的最少颜色数。贪婪着色效率高,并且广泛用于各种应用中,例如调度、图着色和编译器优化中的分配。

算法

  • 初始化一个存储分配给顶点的颜色的集合。当我们为图中的每个顶点分配颜色时,此集合将被更新。

  • 按任何所需的顺序对图的顶点进行排序。对顶点进行排序可以帮助确定处理它们的顺序,并且可能提高着色效率。

  • 对于排序顺序中的每个顶点 v

    • 创建一个其相邻顶点使用的颜色的集合。此集合将存储当前分配给 v 的邻居顶点的颜色。

    • 从使用的颜色集合中找到最小的未使用颜色。遍历使用的颜色集合,并选择未显示的最小颜色

    • 将最小的未使用颜色分配给顶点 v。使用分配给顶点 v 的颜色更新颜色集合。

  • 返回分配给每个顶点的颜色集合。生成的彩色集合将提供有效的顶点着色,其中没有两个相邻的顶点共享相同的颜色。

    贪婪着色算法基于可用颜色和相邻顶点使用的颜色,以贪婪的方式将颜色分配给顶点。虽然它可能不会始终产生图所需的最少颜色数,但它提供了一种快速有效的顶点着色方法。

示例

#include <iostream>
#include <vector>
using namespace std;

const int numVertices = 5, numEdges = 7;

// Variable to store the graph
vector<vector<int>> adjacencyList(numVertices);

// To store whether a vertex is visited or not
int visited[numVertices];

// Boolean value to store whether the graph contains a cycle or not
bool hasCycle;

// Variable to store the color of the edges in the graph
int edgeColors[numEdges];

// Function to traverse the graph using DFS Traversal
void dfs(int vertex)
{
    visited[vertex] = 1;

    // Loop to iterate through all the edges from the source vertex
    for (int adjacentVertex : adjacencyList[vertex]) {
        // If the adjacent vertex is not visited
        if (visited[adjacentVertex] == 0) {
            dfs(adjacentVertex);
            edgeColors[vertex] = 1;
        }

        // Condition to check cross and forward edges of the graph
        else if (visited[adjacentVertex] == 2) {
            edgeColors[vertex] = 1;
        }

        // Presence of Back Edge
        else {
            edgeColors[vertex] = 2;
            hasCycle = true;
        }
    }
    visited[vertex] = 2;
}

// Driver Code
int main()
{
    adjacencyList[0] = {1, 2};
    adjacencyList[1] = {2, 3};
    adjacencyList[2] = {3};
    adjacencyList[3] = {4};
    adjacencyList[4] = {2};

    // Loop to run DFS Traversal on vertices that are not visited
    for (int i = 0; i < numVertices; ++i) {
        if (visited[i] == 0) {
            dfs(i);
        }
    }
    cout << (hasCycle ? 2 : 1) << endl;

    // Loop to print the colors of the edges
    for (int i = 0; i < numEdges; ++i) {
        cout << edgeColors[i] << ' ';
    }
    return 0;
}

输出

2
1 1 1 1 2 0 0 

结论

本文讨论了最小化图中所需颜色数的问题,以便构成环的边不具有相同的颜色。它研究了两种方法:深度优先搜索 (DFS) 结合回溯算法和贪婪着色算法。DFS 方法包括遍历图并根据其与相邻顶点的连接将颜色分配给边。贪婪着色方法以贪婪的方式将颜色分配给顶点,并考虑相邻顶点使用的颜色。这两种方法都旨在找到满足条件并保证没有环具有相同颜色的边的所需的最少颜色数。

更新于: 2023年7月14日

66 次浏览

开启您的 职业生涯

通过完成课程获得认证

开始
广告