:: Protocolo Prim (MST) :: Custo Mínimo ::
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.
#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;
}
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.
O "Peso da Conexão".
Armazena o peso da aresta mais leve que conecta um vértice de fora à árvore. Começa com infinito.
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;
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.
O loop for (count = 0; count < V; count++) executa a lógica principal para cada nó do grafo.
Procura o vértice u que:
mstSet == false)key[]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.
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.