using System.Collections.Generic;
public class SearchResult
public HashSet<Edge<int>> Route = new HashSet<Edge<int>>();
public void AddEdge(Edge<int> e)
public void RemoveEdge(Edge<int> e)
static void Main(String[] args)
var cases = int.Parse(Console.ReadLine());
for (int i = 0; i < cases; i++)
var str = Console.ReadLine();
var tokens = str.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
var n = int.Parse(tokens[0]);
var m = int.Parse(tokens[1]);
var graph4 = new Graph<int>();
for (int j = 0; j < numEdges; j++)
str = Console.ReadLine();
tokens = str.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
var v1 = int.Parse(tokens[0]);
var v2 = int.Parse(tokens[1]);
var d = int.Parse(tokens[2]);
graph4.AddEdge(new Edge<int>(v1, v2, d));
private static void FastApproach(int n, Graph<int> graph)
var mst = KruskalMST(graph);
SearchResult minResult = null;
foreach (var v in mst.Vertices.Keys)
SearchResult result = DFS(mst, v, numVert-1);
if (minResult==null || result.Cost < minResult.Cost)
Console.WriteLine(minResult.Cost);
private static SearchResult DFS(Graph<int> graph, int v, int edgeCount)
var path = new SearchResult();
var bestPath = new SearchResult() { Cost = int.MaxValue };
DFS(graph, path, bestPath, v, edgeCount);
private static void DFS(Graph<int> graph, SearchResult path, SearchResult bestPath, int root, int edgeCount)
var neighbors = graph.Vertices[root];
foreach(var e in neighbors)
if (path.Route.Contains(e)) { continue; }
DFS(graph, path, bestPath, e.Source, edgeCount);
else if (e.Destination != root)
DFS(graph, path, bestPath, e.Destination, edgeCount);
if(path.Cost<bestPath.Cost)
foreach(var pe in path.Route)
private static Graph<int> CreateSubGraph(List<List<Edge<int>>> graph, List<int> vertexSet)
Graph<int> g = new Graph<int>();
foreach (var v in vertexSet)
var neighbors = graph[v];
foreach (var edge in neighbors)
if (vertexSet.Contains(edge.Source) && vertexSet.Contains(edge.Destination))
private static IEnumerable<List<int>> GetSubsetsOld(int n, int numElems)
double rows = Math.Pow(2, n);
for (int counter = 0; counter < rows; counter++)
var subset = new List<int>();
for (var bit = 0; bit < n; bit++)
var signal = counter & (1 << bit);
if (subset.Count == numElems) { subset.Clear(); break; }
if (subset.Count == numElems)
private static IEnumerable<List<int>> GetSubsets(int n, int numElems)
int initial = InitialSet(numElems);
yield return Convert(n, numElems, initial);
int newBits = NewSet(numElems, ref msb);
yield return Convert(n, numElems, newBits);
int pos = FindNextMSB(prev);
newBits = NewSet(numElems, ref msb);
yield return Convert(n, numElems, newBits);
newBits = MoveBit(prev, source, dest);
yield return Convert(n, numElems, newBits);
private static int FindNextMSB(int prev)
while ((prev & 1 << pos) == 0)
while ((prev & 1 << pos) > 0)
private static int NewSet(int numElems, ref int msb)
var newBits = 1 << ++msb;
for (int i = 0; i < rem; i++)
private static int MoveBit(int orig, int source, int destination)
var allBitsSet = int.MinValue;
var rightMask = (1 << source) - 1;
var leftMask = allBitsSet - (1 << (destination + 1));
if (destination - source > 1)
var middleA = (1 << destination) - 1;
var middleB = (1 << source + 1) - 1;
var middleMask = middleA - middleB;
mask = leftMask | middleMask | rightMask;
mask = leftMask | rightMask;
var result = orig & mask;
result |= 1 << destination;
private static int MoveBitOld(int orig, int source, int destination)
if(source>=destination) { throw new InvalidOperationException("Source must be > Destination"); }
for (int pos = 0; pos <= destination; pos++)
else if(pos==destination)
result |= orig & (1 << pos);
private static int InitialSet(int numElems)
for (int i = 0; i < numElems; i++)
private static List<int> Convert(int n, int numElems, int bits)
var subset = new List<int>();
for (var bit = 0; bit < n; bit++)
var signal = bits & (1 << bit);
if (subset.Count == numElems) { break; }
private static int GetMinimumSpanningTree(Graph<int> graph)
var result = KruskalMST(graph);
foreach (var e in result.Edges)
private static Graph<int> KruskalMST(Graph<int> graph)
int numVert = graph.NumVertices;
Graph<int> resultGraph = new Graph<int>();
var edges = new List<Edge<int>>();
foreach (var edge in graph.Edges)
var subsets = new Dictionary<int, Subset>();
foreach (int v in graph.Vertices.Keys)
subsets.Add(v, new Subset(v, 0));
while(resultGraph.Edges.Count < (numVert-1))
var nextEdge = edges[i++];
int x = Find(subsets, nextEdge.Source);
int y = Find(subsets, nextEdge.Destination);
resultGraph.AddEdge(nextEdge);
private static int Find(Dictionary<int, Subset> subsets, int i)
if (subsets[i].Parent != i)
subsets[i].Parent = Find(subsets, subsets[i].Parent);
return subsets[i].Parent;
private static void Union(Dictionary<int, Subset> subsets, int x, int y)
int xroot = Find(subsets, x);
int yroot = Find(subsets, y);
if (subsets[xroot].Rank < subsets[yroot].Rank)
subsets[xroot].Parent = yroot;
else if (subsets[xroot].Rank > subsets[yroot].Rank)
subsets[yroot].Parent = xroot;
subsets[yroot].Parent = xroot;
public TreeNode(T val) { this.Value = val; }
public int NumVertices { get { return this.Vertices.Count; } }
public int NumEdges { get { return this.Edges.Count; } }
public HashSet<Edge<T>> Edges = new HashSet<Edge<T>>();
public Dictionary<T,List<Edge<T>>> Vertices = new Dictionary<T,List<Edge<T>>>();
public void AddEdge(Edge<T> edge)
if (!this.Edges.Contains(edge))
AddEdge(edge.Source, edge);
AddEdge(edge.Destination, edge);
private void AddEdge(T key, Edge<T> edge)
if (!this.Vertices.ContainsKey(key))
list = new List<Edge<T>>();
this.Vertices.Add(key, list);
list = this.Vertices[key];
public Subset(int parent, int rank) { this.Parent = parent; this.Rank = rank; }
public class Edge<T> : IComparable<Edge<T>>
public Edge(T v1, T v2, int weight)
public int CompareTo(Edge<T> other)
return Convert.ToInt32(this.Weight).CompareTo(Convert.ToInt32(other.Weight));