📜  Prim的算法(邻接矩阵表示的简单实现)

📅  最后修改于: 2021-04-23 17:48:38             🧑  作者: Mango

我们已经讨论了图的邻接矩阵表示的Prim算法及其实现。
如前一篇文章所述,在Prim的算法中,维护了两组,一组包含MST中已包含的顶点列表,另一组包含尚未包含的顶点。在每次迭代中,我们都将连接两个集合的边中的最小权重边考虑在内。

先前文章中讨论的实现使用两个数组来找到连接两个集合的最小权重边。在这里,我们使用一个inMST [V]。如果顶点i包含在MST中,则MST [i]的值将为true。在每一遍中,我们仅考虑那些边,以使该边的一个顶点包含在MST中,而另一个不包含。选择一条边后,将两个顶点都标记为包含在MST中。

C++
// A simple C++ implementation to find minimum 
// spanning tree for adjacency representation.
#include 
using namespace std;
#define V 5
  
// Returns true if edge u-v is a valid edge to be
// include in MST. An edge is valid if one end is
// already included in MST and other is not in MST.
bool isValidEdge(int u, int v, vector inMST)
{
   if (u == v)
       return false;
   if (inMST[u] == false && inMST[v] == false)
        return false;
   else if (inMST[u] == true && inMST[v] == true)
        return false;
   return true;
}
  
void primMST(int cost[][V])
{  
    vector inMST(V, false);
  
    // Include first vertex in MST
    inMST[0] = true;
  
    // Keep adding edges while number of included
    // edges does not become V-1.
    int edge_count = 0, mincost = 0;
    while (edge_count < V - 1) {
  
        // Find minimum weight valid edge.  
        int min = INT_MAX, a = -1, b = -1;
        for (int i = 0; i < V; i++) {
            for (int j = 0; j < V; j++) {               
                if (cost[i][j] < min) {
                    if (isValidEdge(i, j, inMST)) {
                        min = cost[i][j];
                        a = i;
                        b = j;
                    }
                }
            }
        }
        if (a != -1 && b != -1) {
            printf("Edge %d:(%d, %d) cost: %d \n", 
                         edge_count++, a, b, min);
            mincost = mincost + min;
            inMST[b] = inMST[a] = true;
        }
    }
    printf("\n Minimum cost= %d \n", mincost);
}
  
// driver program to test above function
int main()
{
    /* Let us create the following graph
          2    3
      (0)--(1)--(2)
       |   / \   |
      6| 8/   \5 |7
       | /     \ |
      (3)-------(4)
            9          */
    int cost[][V] = {
        { INT_MAX, 2, INT_MAX, 6, INT_MAX },
        { 2, INT_MAX, 3, 8, 5 },
        { INT_MAX, 3, INT_MAX, INT_MAX, 7 },
        { 6, 8, INT_MAX, INT_MAX, 9 },
        { INT_MAX, 5, 7, 9, INT_MAX },
    };
  
    // Print the solution
    primMST(cost);
  
    return 0;
}


Java
// A simple Java implementation to find minimum 
// spanning tree for adjacency representation.
import java.util.*;
  
class GFG 
{
  
static int V = 5;
static int INT_MAX = Integer.MAX_VALUE;
  
// Returns true if edge u-v is a valid edge to be
// include in MST. An edge is valid if one end is
// already included in MST and other is not in MST.
static boolean isValidEdge(int u, int v,
                           boolean[] inMST)
{
    if (u == v)
        return false;
    if (inMST[u] == false && inMST[v] == false)
        return false;
    else if (inMST[u] == true && inMST[v] == true)
        return false;
    return true;
}
  
static void primMST(int cost[][])
{ 
    boolean []inMST = new boolean[V];
  
    // Include first vertex in MST
    inMST[0] = true;
  
    // Keep adding edges while number of included
    // edges does not become V-1.
    int edge_count = 0, mincost = 0;
    while (edge_count < V - 1)
    {
  
        // Find minimum weight valid edge. 
        int min = INT_MAX, a = -1, b = -1;
        for (int i = 0; i < V; i++) 
        {
            for (int j = 0; j < V; j++) 
            {             
                if (cost[i][j] < min) 
                {
                    if (isValidEdge(i, j, inMST)) 
                    {
                        min = cost[i][j];
                        a = i;
                        b = j;
                    }
                }
            }
        }
          
        if (a != -1 && b != -1) 
        {
            System.out.printf("Edge %d:(%d, %d) cost: %d \n", 
                                    edge_count++, a, b, min);
            mincost = mincost + min;
            inMST[b] = inMST[a] = true;
        }
    }
    System.out.printf("\n Minimum cost = %d \n", mincost);
}
  
// Driver Code
public static void main(String[] args)
{
    /* Let us create the following graph
        2 3
    (0)--(1)--(2)
    | / \ |
    6| 8/ \5 |7
    | /     \ |
    (3)-------(4)
            9         */
    int cost[][] = {{ INT_MAX, 2, INT_MAX, 6, INT_MAX },
                    { 2, INT_MAX, 3, 8, 5 },
                    { INT_MAX, 3, INT_MAX, INT_MAX, 7 },
                    { 6, 8, INT_MAX, INT_MAX, 9 },
                    { INT_MAX, 5, 7, 9, INT_MAX }};
  
    // Print the solution
    primMST(cost);
}
} 
  
// This code is contributed by Rajput-Ji


Python3
# Python3 implementation to find minimum 
# spanning tree for adjacency representation.
from sys import maxsize
INT_MAX = maxsize
V = 5
  
# Returns true if edge u-v is a valid edge to be 
# include in MST. An edge is valid if one end is 
# already included in MST and other is not in MST.
def isValidEdge(u, v, inMST):
    if u == v:
        return False
    if inMST[u] == False and inMST[v] == False:
        return False
    elif inMST[u] == True and inMST[v] == True:
        return False
    return True
  
def primMST(cost):
    inMST = [False] * V
  
    # Include first vertex in MST
    inMST[0] = True
  
    # Keep adding edges while number of included 
    # edges does not become V-1.
    edge_count = 0
    mincost = 0
    while edge_count < V - 1:
  
        # Find minimum weight valid edge.
        minn = INT_MAX
        a = -1
        b = -1
        for i in range(V):
            for j in range(V):
                if cost[i][j] < minn:
                    if isValidEdge(i, j, inMST):
                        minn = cost[i][j]
                        a = i
                        b = j
  
        if a != -1 and b != -1:
            print("Edge %d: (%d, %d) cost: %d" % 
                 (edge_count, a, b, minn))
            edge_count += 1
            mincost += minn
            inMST[b] = inMST[a] = True
  
    print("Minimum cost = %d" % mincost)
  
# Driver Code
if __name__ == "__main__":
    ''' Let us create the following graph 
        2 3 
    (0)--(1)--(2) 
    | / \ | 
    6| 8/ \5 |7 
    | /     \ | 
    (3)-------(4) 
            9         '''
  
    cost = [[INT_MAX, 2, INT_MAX, 6, INT_MAX], 
            [2, INT_MAX, 3, 8, 5],
            [INT_MAX, 3, INT_MAX, INT_MAX, 7], 
            [6, 8, INT_MAX, INT_MAX, 9],
            [INT_MAX, 5, 7, 9, INT_MAX]]
  
    # Print the solution
    primMST(cost)
  
# This code is contributed by
# sanjeev2552


C#
// A simple C# implementation to find minimum 
// spanning tree for adjacency representation.
using System;
  
class GFG 
{
  
static int V = 5;
static int INT_MAX = int.MaxValue;
  
// Returns true if edge u-v is a valid edge to be
// include in MST. An edge is valid if one end is
// already included in MST and other is not in MST.
static bool isValidEdge(int u, int v,
                        bool[] inMST)
{
    if (u == v)
        return false;
    if (inMST[u] == false && inMST[v] == false)
        return false;
    else if (inMST[u] == true && 
             inMST[v] == true)
        return false;
    return true;
}
  
static void primMST(int [,]cost)
{ 
    bool []inMST = new bool[V];
  
    // Include first vertex in MST
    inMST[0] = true;
  
    // Keep adding edges while number of 
    // included edges does not become V-1.
    int edge_count = 0, mincost = 0;
    while (edge_count < V - 1)
    {
  
        // Find minimum weight valid edge. 
        int min = INT_MAX, a = -1, b = -1;
        for (int i = 0; i < V; i++) 
        {
            for (int j = 0; j < V; j++) 
            {         
                if (cost[i, j] < min) 
                {
                    if (isValidEdge(i, j, inMST)) 
                    {
                        min = cost[i, j];
                        a = i;
                        b = j;
                    }
                }
            }
        }
          
        if (a != -1 && b != -1) 
        {
            Console.Write("Edge {0}:({1}, {2}) cost: {3} \n", 
                                    edge_count++, a, b, min);
            mincost = mincost + min;
            inMST[b] = inMST[a] = true;
        }
    }
    Console.Write("\n Minimum cost = {0} \n", mincost);
}
  
// Driver Code
public static void Main(String[] args)
{
    /* Let us create the following graph
        2 3
    (0)--(1)--(2)
    | / \ |
    6| 8/ \5 |7
    | / \ |
    (3)-------(4)
            9     */
    int [,]cost = {{ INT_MAX, 2, INT_MAX, 6, INT_MAX },
                   { 2, INT_MAX, 3, 8, 5 },
                   { INT_MAX, 3, INT_MAX, INT_MAX, 7 },
                   { 6, 8, INT_MAX, INT_MAX, 9 },
                   { INT_MAX, 5, 7, 9, INT_MAX }};
  
    // Print the solution
    primMST(cost);
}
} 
  
// This code is contributed by PrinciRaj1992


输出:
Edge 0:(0, 1) cost: 2 
Edge 1:(1, 2) cost: 3 
Edge 2:(1, 4) cost: 5 
Edge 3:(0, 3) cost: 6 

 Minimum cost= 16

时间复杂度:O(V 3 )

注意,使用邻接矩阵的先前方法的时间复杂度为O(V 2 ),并且邻接列表表示实现的时间复杂度为O((E + V)LogV)。