using
System;
using
System.Collections.Generic;
public
class
PrimMST
{
private
class
iPair : IComparable<iPair>
{
public
int
First {
get
;
set
; }
public
int
Second {
get
;
set
; }
public
iPair(
int
first,
int
second)
{
First = first;
Second = second;
}
public
int
CompareTo(iPair other)
{
return
First.CompareTo(other.First);
}
}
private
static
void
AddEdge(List<List<iPair>> adj,
int
u,
int
v,
int
wt)
{
adj[u].Add(
new
iPair(v, wt));
adj[v].Add(
new
iPair(u, wt));
}
private
static
void
PrimMSTAlgorithm(List<List<iPair>> adj,
int
V)
{
PriorityQueue<iPair> pq =
new
PriorityQueue<iPair>();
int
src = 0;
List<
int
> key =
new
List<
int
>(
new
int
[V]);
for
(
int
i = 0; i < V; i++)
{
key[i] =
int
.MaxValue;
}
List<
int
> parent =
new
List<
int
>(
new
int
[V]);
for
(
int
i = 0; i < V; i++)
{
parent[i] = -1;
}
List<
bool
> inMST =
new
List<
bool
>(
new
bool
[V]);
pq.Enqueue(
new
iPair(0, src));
key[src] = 0;
while
(pq.Count > 0)
{
int
u = pq.Dequeue().Second;
if
(inMST[u])
{
continue
;
}
inMST[u] =
true
;
foreach
(
var
x
in
adj[u])
{
int
v = x.First;
int
weight = x.Second;
if
(!inMST[v] && key[v] > weight)
{
key[v] = weight;
pq.Enqueue(
new
iPair(key[v], v));
parent[v] = u;
}
}
}
for
(
int
i = 1; i < V; ++i)
{
Console.WriteLine($
"{parent[i]} - {i}"
);
}
}
public
static
void
Main()
{
int
V = 9;
List<List<iPair>> adj =
new
List<List<iPair>>(
new
List<iPair>[V]);
for
(
int
i = 0; i < V; ++i)
{
adj[i] =
new
List<iPair>();
}
AddEdge(adj, 0, 1, 4);
AddEdge(adj, 0, 7, 8);
AddEdge(adj, 1, 2, 8);
AddEdge(adj, 1, 7, 11);
AddEdge(adj, 2, 3, 7);
AddEdge(adj, 2, 8, 2);
AddEdge(adj, 2, 5, 4);
AddEdge(adj, 3, 4, 9);
AddEdge(adj, 3, 5, 14);
AddEdge(adj, 4, 5, 10);
AddEdge(adj, 5, 6, 2);
AddEdge(adj, 6, 7, 1);
AddEdge(adj, 6, 8, 6);
AddEdge(adj, 7, 8, 7);
PrimMSTAlgorithm(adj, V);
}
}
public
class
PriorityQueue<T>
where
T : IComparable<T>
{
private
List<T> heap;
public
int
Count => heap.Count;
public
PriorityQueue()
{
heap =
new
List<T>();
}
public
void
Enqueue(T item)
{
heap.Add(item);
int
i = heap.Count - 1;
while
(i > 0)
{
int
parent = (i - 1) / 2;
if
(heap[parent].CompareTo(heap[i]) <= 0)
break
;
Swap(parent, i);
i = parent;
}
}
public
T Dequeue()
{
if
(heap.Count == 0)
throw
new
InvalidOperationException(
"Priority queue is empty."
);
T item = heap[0];
int
lastIndex = heap.Count - 1;
heap[0] = heap[lastIndex];
heap.RemoveAt(lastIndex);
int
i = 0;
while
(
true
)
{
int
leftChild = 2 * i + 1;
if
(leftChild >= heap.Count)
break
;
int
rightChild = leftChild + 1;
int
minChild = (rightChild < heap.Count && heap[rightChild].CompareTo(heap[leftChild]) < 0) ? rightChild : leftChild;
if
(heap[i].CompareTo(heap[minChild]) <= 0)
break
;
Swap(i, minChild);
i = minChild;
}
return
item;
}
private
void
Swap(
int
i,
int
j)
{
T temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
}