📌  相关文章
📜  最小化为无向图的所有顶点着色的成本

📅  最后修改于: 2021-09-03 04:12:52             🧑  作者: Mango

给定一个由N个顶点和M 个边组成的无向图,其中节点值在[1, N]范围内,并且由数组coloured[]指定的顶点被着色,任务是找到给定的所有顶点的最小颜色图形。为顶点着色的成本由vCost给出,在两个顶点之间添加新边的成本由eCost给出。如果一个顶点被着色,那么从该顶点可以到达的所有顶点也被着色。

例子:

方法:
这个想法是使用 DFS Traversal 计算未着色顶点的子图的数量
为了最大限度地减少色素的无色子图的成本,做了以下需求之一:

  • 为子图着色
  • 在任何有色和无色顶点之间添加一条边。

基于eCostvCost的最小值,需要选择以上两个步骤之一。
如果未着色子图的数量由X给出,则为所有顶点着色的总成本由X×min(eCost, vCost) 给出

按照以下步骤查找未着色子图的数量:

  1. 对所有彩色顶点执行 DFS 遍历并将它们标记为已访问以将它们标识为彩色。
  2. 在步骤 1 的 DFS 之后未访问的顶点是未着色的顶点。
  3. 对于每个未着色的顶点,使用 DFS 将可以从该顶点到达的所有顶点标记为已访问。
  4. 发生第 3 步 DFS 的未着色顶点的数量是子图的数量X。
  5. 通过公式X×min(eCost, vCost)计算所有顶点着色的总成本

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
 
// Function to implement DFS Traversal
// to marks all the vertices visited
// from vertex U
void DFS(int U, int* vis, vector adj[])
{
    // Mark U as visited
    vis[U] = 1;
 
    // Traverse the adjacency list of U
    for (int V : adj[U]) {
        if (vis[V] == 0)
            DFS(V, vis, adj);
    }
}
 
// Function to find the minimum cost
// to color all the vertices of graph
void minCost(int N, int M, int vCost,
             int eCost, int sorc[],
             vector colored,
             int destination[])
{
    // To store adjacency list
    vector adj[N + 1];
 
    // Loop through the edges to
    // create adjacency list
    for (int i = 0; i < M; i++) {
 
        adj[sorc[i]].push_back(destination[i]);
        adj[destination[i]].push_back(sorc[i]);
    }
 
    // To check if a vertex of the
    // graph is visited
    int vis[N + 1] = { 0 };
 
    // Mark visited to all the vertices
    // that can be reached by
    // colored vertices
    for (int i = 0; i < colored.size(); i++) {
 
        // Perform DFS
        DFS(colored[i], vis, adj);
    }
 
    // To store count of uncolored
    // sub-graphs
    int X = 0;
 
    // Loop through vertex to count
    // uncolored sub-graphs
    for (int i = 1; i <= N; i++) {
 
        // If vertex not visited
        if (vis[i] == 0) {
 
            // Increase count of
            // uncolored sub-graphs
            X++;
 
            // Perform DFS to mark
            // visited to all vertices
            // of current sub-graphs
            DFS(i, vis, adj);
        }
    }
 
    // Calculate minimum cost to color
    // all vertices
    int mincost = X * min(vCost, eCost);
 
    // Print the result
    cout << mincost << endl;
}
 
// Driver Code
int main()
{
 
    // Given number of
    // vertices and edges
    int N = 3, M = 1;
 
    // Given edges
    int sorc[] = { 1 };
    int destination[] = { 2 };
 
    // Given cost of coloring
    // and adding an edge
    int vCost = 3, eCost = 2;
 
    // Given array of
    // colored vertices
    vector colored = { 1};
 
    minCost(N, M, vCost, eCost,
            sorc, colored, destination);
 
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
     
// Function to implement DFS Traversal
// to marks all the vertices visited
// from vertex U
static void DFS(int U, int[] vis,
                ArrayList> adj)
{
     
    // Mark U as visited
    vis[U] = 1;
  
    // Traverse the adjacency list of U
    for(Integer V : adj.get(U))
    {
        if (vis[V] == 0)
            DFS(V, vis, adj);
    }
}
  
// Function to find the minimum cost
// to color all the vertices of graph
static void minCost(int N, int M, int vCost,
                    int eCost, int sorc[],
                    ArrayList colored,
                    int destination[])
{
     
    // To store adjacency list
    ArrayList> adj = new ArrayList<>();
  
    for(int i = 0; i < N + 1; i++)
        adj.add(new ArrayList());
  
    // Loop through the edges to
    // create adjacency list
    for(int i = 0; i < M; i++)
    {
        adj.get(sorc[i]).add(destination[i]);
        adj.get(destination[i]).add(sorc[i]);
    }
  
    // To check if a vertex of the
    // graph is visited
    int[] vis = new int[N + 1];
  
    // Mark visited to all the vertices
    // that can be reached by
    // colored vertices
    for(int i = 0; i < colored.size(); i++)
    {
         
        // Perform DFS
        DFS(colored.get(i), vis, adj);
    }
  
    // To store count of uncolored
    // sub-graphs
    int X = 0;
  
    // Loop through vertex to count
    // uncolored sub-graphs
    for(int i = 1; i <= N; i++)
    {
         
        // If vertex not visited
        if (vis[i] == 0)
        {
             
            // Increase count of
            // uncolored sub-graphs
            X++;
  
            // Perform DFS to mark
            // visited to all vertices
            // of current sub-graphs
            DFS(i, vis, adj);
        }
    }
  
    // Calculate minimum cost to color
    // all vertices
    int mincost = X * Math.min(vCost, eCost);
  
    // Print the result
    System.out.println(mincost);
}
 
// Driver code
public static void main(String[] args)
{
     
    // Given number of
    // vertices and edges
    int N = 3, M = 1;
     
    // Given edges
    int sorc[] = {1};
    int destination[] = {2};
     
    // Given cost of coloring
    // and adding an edge
    int vCost = 3, eCost = 2;
     
    // Given array of
    // colored vertices
    ArrayList colored = new ArrayList<>();
    colored.add(1);
     
    minCost(N, M, vCost, eCost, sorc,
            colored, destination);
}
}
 
// This code is contributed by offbeat


Python3
# Python3 program to implement
# the above approach
 
# Function to implement DFS Traversal
# to marks all the vertices visited
# from vertex U
def DFS(U, vis, adj):
     
    # Mark U as visited
    vis[U] = 1
 
    # Traverse the adjacency list of U
    for V in adj[U]:
        if (vis[V] == 0):
            DFS(V, vis, adj)
 
# Function to find the minimum cost
# to color all the vertices of graph
def minCost(N, M, vCost, eCost, sorc,
            colored, destination):
                 
    # To store adjacency list
    adj = [[] for i in range(N + 1)]
 
    # Loop through the edges to
    # create adjacency list
    for i in range(M):
        adj[sorc[i]].append(destination[i])
        adj[destination[i]].append(sorc[i])
 
    # To check if a vertex of the
    # graph is visited
    vis = [0] * (N + 1)
 
    # Mark visited to all the vertices
    # that can be reached by
    # colored vertices
    for i in range(len(colored)):
 
        # Perform DFS
        DFS(colored[i], vis, adj)
 
    # To store count of uncolored
    # sub-graphs
    X = 0
 
    # Loop through vertex to count
    # uncolored sub-graphs
    for i in range(1, N + 1):
 
        # If vertex not visited
        if (vis[i] == 0):
 
            # Increase count of
            # uncolored sub-graphs
            X += 1
 
            # Perform DFS to mark
            # visited to all vertices
            # of current sub-graphs
            DFS(i, vis, adj)
 
    # Calculate minimum cost to color
    # all vertices
    mincost = X * min(vCost, eCost)
 
    # Print the result
    print(mincost)
 
# Driver Code
if __name__ == '__main__':
 
    # Given number of
    # vertices and edges
    N = 3
    M = 1
 
    # Given edges
    sorc = [1]
    destination = [2]
 
    # Given cost of coloring
    # and adding an edge
    vCost = 3
    eCost = 2
 
    # Given array of
    # colored vertices
    colored = [1]
 
    minCost(N, M, vCost, eCost,
            sorc, colored, destination)
 
# This code is contributed by mohit kumar 29


C#
// C# program to implement
// the above approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG{
     
// Function to implement DFS Traversal
// to marks all the vertices visited
// from vertex U
static void DFS(int U, int[] vis, ArrayList adj)
{
   
    // Mark U as visited
    vis[U] = 1;
 
    // Traverse the adjacency list of U
    foreach(int V in (ArrayList)adj[U])
    {
        if (vis[V] == 0)
            DFS(V, vis, adj);
    }
}
 
// Function to find the minimum cost
// to color all the vertices of graph
static void minCost(int N, int M, int vCost,
                    int eCost, int []sorc,
                    ArrayList colored,
                    int []destination)
{
     
    // To store adjacency list
    ArrayList adj = new ArrayList();
 
    for(int i = 0; i < N + 1; i++)
        adj.Add(new ArrayList());
 
    // Loop through the edges to
    // create adjacency list
    for(int i = 0; i < M; i++)
    {
        ((ArrayList)adj[sorc[i]]).Add(destination[i]);
        ((ArrayList)adj[destination[i]]).Add(sorc[i]);
    }
 
    // To check if a vertex of the
    // graph is visited
    int[] vis = new int[N + 1];
 
    // Mark visited to all the vertices
    // that can be reached by
    // colored vertices
    for(int i = 0; i < colored.Count; i++)
    {
         
        // Perform DFS
        DFS((int)colored[i], vis, adj);
    }
   
    // To store count of uncolored
    // sub-graphs
    int X = 0;
 
    // Loop through vertex to count
    // uncolored sub-graphs
    for(int i = 1; i <= N; i++)
    {
       
        // If vertex not visited
        if (vis[i] == 0)
        {
             
            // Increase count of
            // uncolored sub-graphs
            X++;
 
            // Perform DFS to mark
            // visited to all vertices
            // of current sub-graphs
            DFS(i, vis, adj);
        }
    }
 
    // Calculate minimum cost to color
    // all vertices
    int mincost = X * Math.Min(vCost, eCost);
 
    // Print the result
    Console.Write(mincost);
}
 
// Driver code
public static void Main(string[] args)
{
     
    // Given number of
    // vertices and edges
    int N = 3, M = 1;
     
    // Given edges
    int []sorc = {1};
    int []destination = {2};
     
    // Given cost of coloring
    // and adding an edge
    int vCost = 3, eCost = 2;
     
    // Given array of
    // colored vertices
    ArrayList colored = new ArrayList();
    colored.Add(1);
     
    minCost(N, M, vCost, eCost,
            sorc, colored,
            destination);
}
}
 
// This code is contributed by rutvik_56


输出:
2

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live