import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.LinkedList;
import java.util.Comparator;
import java.util.Set;
public class Prim {
public class Node {
public int value;
public int in;
public int out;
public ArrayList<Node> nexts;
public ArrayList<Edge> edges;
Node(int va) {
this.value = va;
in = out = 0;
nexts = new ArrayList<Node>();
edges = new ArrayList<Edge>();
}
}
public class Edge {
public int weight;
public Node from;
public Node to;
Edge(int weight, Node from, Node to) {
this.weight = weight;
this.from = from;
this.to = to;
}
}
public class Graph {
public HashMap<Integer, Node> nodes;
public HashSet<Edge> edges;
Graph() {
nodes = new HashMap<Integer, Node>();
edges = new HashSet<Edge>();
}
}
public static class EdgeComparator implements Comparator<Edge> {
public int compare(Edge a, Edge b) { return a.weight - b.weight; }
}
public static Set<Edge> PrimMST(Graph graph) {
PriorityQueue<Edge> priorityQueue =
new PriorityQueue<Edge>(new EdgeComparator());
HashSet<Node> set = new HashSet<Node>();
Set<Edge> result = new HashSet<Edge>();
for (Node node : graph.nodes.values()) {
if (!set.contains(node)) {
set.add(node);
for (Edge edge : node.edges) {
priorityQueue.add(edge);
}
while (!priorityQueue.isEmpty()) {
Edge edge = priorityQueue.poll();
Node toNode = edge.to;
if (!set.contains(toNode)) {
set.add(toNode);
result.add(edge);
for (Edge nextEdge : toNode.edges) {
priorityQueue.add(nextEdge);
}
}
}
}
}
return result;
}
}