static void Main(string[] args) { int t = int.Parse(Console.ReadLine()); for (int k = 0; k < t; k++) { string[] g = Console.ReadLine().Split(' '); TreeNode[] nodes = new TreeNode[int.Parse(g[0])]; Edge[] edges = new Edge[int.Parse(g[1])]; int[,] graph = new int[nodes.Length, nodes.Length]; for (int i = 0; i < edges.Length; i++) { string[] edge = Console.ReadLine().Split(' '); edges[i] = new Edge(); edges[i].x = int.Parse(edge[0]) - 1; edges[i].y = int.Parse(edge[1]) - 1; edges[i].w = int.Parse(edge[2]); graph[edges[i].x, edges[i].y] = graph[edges[i].y, edges[i].x] = edges[i].w; if (nodes[edges[i].x] == null) { nodes[edges[i].x] = new TreeNode(); nodes[edges[i].x].value = edges[i].x; nodes[edges[i].x].rank = 0; nodes[edges[i].x].p = nodes[edges[i].x]; } if (nodes[edges[i].y] == null) { nodes[edges[i].y] = new TreeNode(); nodes[edges[i].y].value = edges[i].y; nodes[edges[i].y].rank = 0; nodes[edges[i].y].p = nodes[edges[i].y]; } } List<Edge> tree = new List<Edge>(); int ans1 = kruskal(nodes, edges, tree); int ans2 = second_mst(graph, tree, ans1); if(edges.Length != nodes.Length - 1) Console.WriteLine("{0} {1}", ans1, ans2); else Console.WriteLine(ans1); } }
static TreeNode find_set(TreeNode[] nodes, int x) { if (nodes[x].p != nodes[x]) nodes[x].p = find_set(nodes, nodes[x].p.value); return nodes[x].p; }
static void union(TreeNode[] nodes, int x, int y) { link(find_set(nodes, x), find_set(nodes, y)); }
private static void link(TreeNode x, TreeNode y) { if (x.rank > y.rank) y.p = x; else { x.p = y; if (x.rank == y.rank) y.rank++; } }
static int kruskal(TreeNode[] nodes, Edge[] edges, List<Edge> tree) { int res = 0; Array.Sort(edges, new EdgeComparer()); for (int i = 0; i < edges.Length; i++) { if (find_set(nodes, edges[i].x) != find_set(nodes, edges[i].y)) { res += edges[i].w; tree.Add(edges[i]); union(nodes, edges[i].x, edges[i].y); if (tree.Count == nodes.Length - 1) break; } } return res; }