using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Algorithms.Graph { public class KruskalsAlgorithm { public class DisjointSetUnion { private int[] parent, rank; public DisjointSetUnion(int totalNodes) { rank = Enumerable.Repeat(1, totalNodes + 1).ToArray(); parent = Enumerable.Range(0, totalNodes + 1).ToArray(); } public void Union(int nodeA, int nodeB) { int parentA = Find(nodeA); int parentB = Find(nodeB); if(rank[parentA] > rank[parentB]) { parent[parentB] = parentA; rank[parentA] += rank[parentB]; } else { parent[parentA] = parentB; rank[parentB] += rank[parentA]; } } public int Find(int node) { if(parent[node] == node) { return node; } return parent[node] = Find(parent[node]); } } public class Graph { private DisjointSetUnion _nodesTaken; private List> edges; public Graph(int totalNodes) { _nodesTaken = new DisjointSetUnion(totalNodes); edges = new List>(); } public void AddEdge(int source, int destination, int weight) => edges.Add(new Tuple(source, destination, weight)); public List> GetMST() { edges = (from edge in edges orderby edge.Item3 select edge).ToList(); List> results = new List>(); foreach(var edge in edges) { if(_nodesTaken.Find(edge.Item1) != _nodesTaken.Find(edge.Item2)) { _nodesTaken.Union(edge.Item1, edge.Item2); results.Add(new Tuple(edge.Item1, edge.Item2, edge.Item3)); } } return results; } } public static Object KruskalDriver(int totalNodes, List> edges) { Graph graph = new Graph(totalNodes); foreach(var edge in edges) { graph.AddEdge(edge.Item1, edge.Item2, edge.Item3); } var results = graph.GetMST(); int totalWeight = 0; foreach(var edge in results) { totalWeight += edge.Item3; } Object ret = new { weight = totalWeight, edges = results }; return ret; } public static void Main() { List> edges = new List>() { new Tuple(1, 2, 4), new Tuple(1, 8, 8), new Tuple(2, 8, 11), new Tuple(2, 3, 8), new Tuple(3, 9, 2), new Tuple(8, 9, 7), new Tuple(8, 7, 1), new Tuple(7, 9, 6), new Tuple(3, 4, 7), new Tuple(3, 6, 4), new Tuple(6, 7, 2), new Tuple(4, 6, 14), new Tuple(4, 5, 9), new Tuple(5, 6, 10) }; var result = KruskalDriver(9, edges); var propertyInfo = result.GetType().GetProperty("weight"); var weight = propertyInfo.GetValue(result, null); Console.WriteLine(weight); } } }