{"record":{"id":"f2741e95649371d2","repo":"TheAlgorithms/C-Sharp","slug":"graph-must-be-undirected","errorCode":null,"errorMessage":"Graph must be undirected!","messagePattern":"Graph must be undirected!","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Algorithms/Graph/MinimumSpanningTree/Kruskal.cs","lineNumber":158,"sourceCode":"                    throw new ArgumentException(\"Matrix must be symmetric!\");\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    ///     Ensure that the given graph is undirected.\n    /// </summary>\n    /// <param name=\"adj\">Adjacency list of graph to check.</param>\n    private static void ValidateGraph(Dictionary<int, float>[] adj)\n    {\n        for (var i = 0; i < adj.Length; i++)\n        {\n            foreach (var edge in adj[i])\n            {\n                if (!adj[edge.Key].ContainsKey(i) || Math.Abs(edge.Value - adj[edge.Key][i]) > 1e-6)\n                {\n                    throw new ArgumentException(\"Graph must be undirected!\");\n                }\n            }\n        }\n    }\n\n    /// <summary>\n    ///     Determine the minimum spanning tree/forest.\n    /// </summary>\n    /// <param name=\"set\">Disjoint set needed for set operations.</param>\n    /// <param name=\"nodes\">List of nodes in disjoint set associated with each node.</param>\n    /// <param name=\"edgeWeights\">Weights of each edge.</param>\n    /// <param name=\"connections\">Nodes associated with each item in the <paramref name=\"edgeWeights\"/> parameter.</param>\n    /// <returns>Array of edges in the minimum spanning tree/forest.</returns>\n    private static (int, int)[] Solve(DisjointSet<int> set, Node<int>[] nodes, float[] edgeWeights, (int, int)[] connections)\n    {\n        var edges = new List<(int, int)>();\n\n        Array.Sort(edgeWeights, connections);","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/TheAlgorithms/C-Sharp/blob/96e2905cab7bc6b33ac0a34ee5bb82ddccbcbb6c/Algorithms/Graph/MinimumSpanningTree/Kruskal.cs#L140-L176","documentation":"When Krkal's MST solver is given an adjacency list (Dictionary<int, Dictionary<int, float>>), ValidateGraph verifies that the graph is undirected: for every edge i -> j with weight w, there must be a reverse edge j -> i with the same weight (within 1e-6). Solve calls this validation and throws ArgumentException when a reverse edge is missing or has a different weight. Without this check the algorithm would traverse an edge in only one direction and produce an incorrect spanning tree.","triggerScenarios":"Calling Kruskal.Solve with an adjacency-list dictionary where some edge entry adj[i] contains key j but adj[j] either does not contain key i (missing reverse edge) or maps it to a weight differing by more than 1e-6.","commonSituations":"Building the dictionary from a directed edge list and only adding adj[i][j]; merging edge data where one direction got a different weight; editing one side of an edge during preprocessing; deserializing edge lists that deduplicated by source only.","solutions":["Mirror every edge when building the dictionary: whenever you set adj[i][j] = w, also set adj[j][i] = w.","Write a symmetrization step that walks all (i,j,w) pairs and inserts or overwrites the reverse entry adj[j][i] = w before calling Solve.","If the reverse edge exists but has a different weight, decide the correct value (usually min or max of the two) and make both directions consistent.","Verify keys exist both ways before calling Solve; a missing reverse key is the most common variant of this error."],"exampleFix":"// before\nadj[0][1] = 4f;\n\n// after\nadj[0][1] = 4f;\nif (!adj.TryGetValue(1, out var rev)) { rev = new Dictionary<int, float>(); adj[1] = rev; }\nrev[0] = 4f; // mirror the edge","handlingStrategy":"validation","validationCode":"static bool IsUndirected(Dictionary<int, Dictionary<int, float>> adj)\n{\n    foreach (var (i, edges) in adj)\n        foreach (var (j, w) in edges)\n            if (!adj.TryGetValue(j, out var rev) || !rev.TryGetValue(i, out var rw) || Math.Abs(w - rw) > 1e-6)\n                return false;\n    return true;\n}\nif (!IsUndirected(adj)) throw new ArgumentException(\"adjacency list is not undirected\");","typeGuard":"static bool IsUndirectedAdjacencyList(Dictionary<int, Dictionary<int, float>> adj) => IsUndirected(adj);","tryCatchPattern":"try\n{\n    var mst = kruskal.Solve(adj);\n}\ncatch (ArgumentException ex) when (ex.Message == \"Graph must be undirected!\")\n{\n    // add missing/mismatched reverse edges, then retry\n}","preventionTips":["Use a single AddEdge(i, j, w) helper that writes both directions","Never mutate one side of an edge without the other","Round or derive both directional weights from the same source value","Unit-test every graph fixture with an undirectedness check"],"tags":["csharp","graph","mst","adjacency-list","input-validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"96e2905cab7bc6b33ac0a34ee5bb82ddccbcbb6c","analyzedAt":"2026-09-13T17:04:01.438Z","contentChangedAt":"2026-09-13T17:04:01.438Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}