Análise de Algoritmo

:: Protocolo Prim (MST) :: Custo Mínimo ::

> Objetivo do Sistema

O código abaixo implementa o Algoritmo de Prim para encontrar a Árvore Geradora Mínima (MST). Ele conecta todos os vértices de um grafo com o menor peso possível.

FILE: source_code.c

READ ONLY

#include <limits.h> // Para usar INT_MAX (infinito)
#include <stdbool.h> // Para usar o tipo bool (true/false)

// Defina o número de vértices (V) do seu grafo.
#define V 5

/**
* @brief Calcula o custo total da MST de um grafo usando Prim.
* @param graph Matriz de adjacência V x V representando o grafo.
* @return O custo total (soma dos pesos das arestas) da MST.
*/
int calcularCustoPrim(int graph[V][V]) {
    
    // key[i] armazena o menor peso da aresta que conecta
    // o vértice 'i' (que está fora da árvore) a qualquer
    // vértice que já está dentro da árvore.
    int key[V];
    
    // mstSet[i] marca 'true' se o vértice 'i' já foi
    // incluído na árvore (MST).
    bool mstSet[V];

    // 1. Inicialização
    // Define todos os custos como Infinito e ninguém na árvore.
    for (int i = 0; i < V; i++) {
        key[i] = INT_MAX;
        mstSet[i] = false;
    }

    // 2. Começa pelo primeiro vértice (pode ser qualquer um)
    // O custo para "chegar" no primeiro vértice é 0.
    key[0] = 0;

    // O loop principal roda V vezes (uma para cada vértice)
    for (int count = 0; count < V; count++) {
        
        // --- 3. Encontra o vértice mais próximo ---
        // (Esta parte substitui a função auxiliar 'minKey')
        
        int min = INT_MAX; // Custo mínimo encontrado nesta rodada
        int u = -1;        // O índice do vértice com o custo mínimo

        // Procura em TODOS os vértices...
        for (int v = 0; v < V; v++) {
            // ...um vértice 'v' que ainda NÃO esteja na árvore
            // e que tenha um custo (key[v]) menor do que o mínimo
            // que encontramos até agora.
            if (mstSet[v] == false && key[v] < min) {
                min = key[v];
                u = v; // 'u' é o nosso candidato para adicionar à árvore
            }
        }
        
        // (Se 'u' for -1, o grafo é desconexo, mas vamos ignorar por simplicidade)
        
        // 4. Adiciona o vértice encontrado 'u' à árvore
        mstSet[u] = true;

        // 5. Atualiza os custos dos vizinhos de 'u'
        // Agora que 'u' está na árvore, vemos se ele oferece um
        // caminho mais barato para algum de seus vizinhos.
        for (int v = 0; v < V; v++) {
            
            // Condições:
            // 1. graph[u][v] != 0 : Existe uma aresta entre 'u' e 'v'.
            // 2. mstSet[v] == false : O vizinho 'v' ainda NÃO está na árvore.
            // 3. graph[u][v] < key[v] : A aresta (u,v) é mais barata
            //                       do que o custo atual para chegar em 'v'.
            if (graph[u][v] && mstSet[v] == false && graph[u][v] < key[v]) {
                
                // Se sim, atualiza o custo de 'v'
                key[v] = graph[u][v];
            }
        }
    }

    // 6. Calcula o custo total
    // O custo total do MST é a soma de todos os valores no array 'key',
    // pois cada key[i] representa o peso da aresta que o conectou à árvore.
    int custoTotal = 0;
    for (int i = 0; i < V; i++) {
        if (key[i] != INT_MAX) { // Evita somar infinito
          custoTotal += key[i];
        }
    }

    return custoTotal;
}

Análise Detalhada

INIT

01. Estrutura Básica

Definição das dependências e constantes.

  • > limits.h: Importa o valor INT_MAX (Infinito). Essencial para representar distâncias desconhecidas.
  • > stdbool.h: Permite o uso de lógica booleana moderna (true/false) em C.
  • > #define V 5: Define o tamanho fixo da matriz de adjacência.
5
Vértices

02. Arrays de Controle

int key[V]

O "Peso da Conexão".

Armazena o peso da aresta mais leve que conecta um vértice de fora à árvore. Começa com infinito.

bool mstSet[V]

O "Checklist".

Um vetor de flags. Se true, o vértice já faz parte da solução final.

for (int i = 0; i < V; i++) {
    key[i] = INT_MAX;
    mstSet[i] = false;
}
key[0] = 0;

03. Reset do Sistema

Prepara o terreno. Assumimos o pior cenário (custo infinito) para todos.

Ponto de Inserção

Definimos key[0] = 0. Isso força o algoritmo a escolher o vértice 0 como o primeiro nó da árvore.

LOOP

04. Núcleo de Processamento

O loop for (count = 0; count < V; count++) executa a lógica principal para cada nó do grafo.

A. Seleção (Greedy)

Procura o vértice u que:

  • Não está na MST (mstSet == false)
  • Tem o menor valor em key[]
min = key[v]; u = v;

B. Atualização Vizinhos

Para cada vizinho v de u:

Se a aresta graph[u][v] for menor que o valor que já temos em key[v], atualizamos! Encontramos um caminho melhor.

key[v] = graph[u][v];

05. Somatório Final

Iteramos pelo array key[] uma última vez. A soma de todos os valores representa o custo mínimo total para conectar todos os pontos da rede.