cs146/10-labMST/Assignment.java

150 lines
4.7 KiB
Java

package labMST;
import java.io.*;
import java.util.*;
public class Assignment {
static class Graph {
private int n; // No. of vertices
private List<List<Integer>> adj; // An array of adjacency lists
private Map<String, Integer> weightMap;
public Graph(int n) {
this.n = n;
this.adj = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
this.adj.add(new LinkedList<>());
}
this.weightMap = new HashMap<>();
}
public void addEdge(int u, int v) {
this.adj.get(u).add(v);
}
public void addEdgeWeight(int u, int v, int w) {
String e = u + "," + v;
this.weightMap.put(e, w);
}
public int getWeight(int u, int v) {
String e = u + "," + v;
return this.weightMap.get(e);
}
public List<Integer> getAdjacent(int u) {
return this.adj.get(u);
}
public int getLength() {
return this.n;
}
public void show() {
for (int v = 0; v < n; v++) {
System.out.print(v + ":");
for (int i : this.adj.get(v)) {
System.out.print(i + ";");
}
System.out.println();
}
}
}
static class QNode {
int id;
int key;
boolean isValid;
int pi;
public QNode() {
id = -1;
key = -1;
isValid = true;
pi = -1;
}
}
// Implement Prim's Algorithm for finding the Minimum Spanning Tree.
// Return the QNode for each vertex in the graph, indicating the parent (pi)
// of every vertex in the resulting tree. Other fields of QNode are optional
// but may be useful in your implementation.
public static List<QNode> Prim(Graph g) {
// Initialize the QNode list
List<QNode> qNodes = new ArrayList<>(g.getLength());
for (int i = 0; i < g.getLength(); i++) {
qNodes.add(new QNode());
qNodes.get(i).id = i;
// Set key to max value for lowest priority
qNodes.get(i).key = Integer.MAX_VALUE;
}
// Start from the first vertex
qNodes.get(0).key = 0;
// Priority queue to select the vertex with the minimum key as the next to be added to the MST
PriorityQueue<QNode> pq = new PriorityQueue<>(Comparator.comparingInt(qNode -> qNode.key));
// Add the first vertex to the priority queue
pq.add(qNodes.get(0));
while (!pq.isEmpty()) {
// Get the vertex with the minimum key
QNode u = pq.poll();
// Mark it as part of the MST
u.isValid = false;
// For each adjacent vertex,
// if it is not already in the MST and the weight is less than the current key
// update the key and parent (pi)
for (int v : g.getAdjacent(u.id)) {
if (qNodes.get(v).isValid && g.getWeight(u.id, v) < qNodes.get(v).key) {
qNodes.get(v).key = g.getWeight(u.id, v);
qNodes.get(v).pi = u.id;
pq.add(qNodes.get(v));
}
}
}
return qNodes;
}
public static void run(String inputPath) {
try (BufferedReader br = new BufferedReader(new FileReader(inputPath))) {
// Read graph
// n is # of nodes. nodes are indexed by 0, 1, 2, ..., n -1
int n = Integer.parseInt(br.readLine().trim());
// # of edges.
int m = Integer.parseInt(br.readLine().trim());
// Build the graph based on the edges on remaining input lines
Graph g = new Graph(n);
for (int i = 0; i < m; i++) {
String[] parts = br.readLine().trim().split(" ");
int s = Integer.parseInt(parts[0]);
int t = Integer.parseInt(parts[1]);
g.addEdge(s, t);
int w = Integer.parseInt(parts[2]);
g.addEdgeWeight(s, t, w);
g.addEdge(t, s);
g.addEdgeWeight(t, s, w);
}
// Your implementation must return a list of QNode. One QNode for
// each vertex, in the order 0, 1, 2, ..., n-1
List<QNode> pQNode = Prim(g);
// The correctness of your implementation will be judged by printing
// the parent of each vertex, line by line
for (int i = 1; i < n; i++) {
System.out.println(pQNode.get(i).pi);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}