1. 程式人生 > 實用技巧 >Minimum Spanning Tree Gym - 102220E

Minimum Spanning Tree Gym - 102220E

In the mathematical discipline of graph theory, the line graph of a simple undirected weighted graphGGis another simple undirected weighted graphL(G)L(G)that represents the adjacency between every two edges inGG.

Precisely speaking, for an undirected weighted graphGGwithout loops or multiple edges, its line graph

L(G)L(G)is a graph such that:

  • Each vertex ofL(G)L(G)represents an edge ofGG.
  • Two vertices ofL(G)L(G)are adjacent if and only if their corresponding edges share a common endpoint inGG, and the weight of such edge between this two vertices is the sum of their corresponding edges' weight.

A minimum spanning tree(MST) or minimum weight spanning tree is a subset of the edges of a connected, edge-weighted undirected graph that connects all the vertices together, without any cycles and with the minimum possible total edge weight. That is, it is a spanning tree whose sum of edge weights is as small as possible.

Given a treeGG, please write a program to find the minimum spanning tree ofL(G)L(G).

Input

The first line of the input contains an integerT(1T1000)T(1≤T≤1000), denoting the number of test cases.

In each test case, there is one integern(2n100000)n(2≤n≤100000)in the first line, denoting the number of vertices of

GG.

For the nextn1n−1lines, each line contains three integersu,v,w(1u,vn,uv,1w109)u,v,w(1≤u,v≤n,u≠v,1≤w≤109), denoting a bidirectional edge between vertexuuandvvwith weightww.

It is guaranteed thatn106∑n≤106.

Output

For each test case, print a single line containing an integer, denoting the sum of all the edges' weight ofMST(L(G))MST(L(G)).

Example

Input
2
4
1 2 1
2 3 2
3 4 3
4
1 2 1
1 3 1
1 4 1
Output
8
4

一棵 n 個點的樹 G,G 的線圖 L(G) 中連線 (u, v) 的邊權為它們對應樹上兩條邊的邊權之和。 求 L(G) 的最小生成樹的邊權和。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+10;
int Case, n, i, j, x, y, z; 
vector<int>tree[N]; 
ll ans;
int main() {
    scanf("%d", &Case);
    while (Case--) {
        scanf("%d", &n);
        for (i = 1; i <= n; i++)tree[i].clear();
        for (i = 1; i < n; i++) {
            scanf("%d%d%d", &x, &y, &z);
            tree[x].push_back(z), tree[y].push_back(z);
        }
        ans = 0;
        for (i = 1; i <= n; i++) {
            if (tree[i].size() > 1) {
                sort(tree[i].begin(), tree[i].end());
                for (j = 1; j < tree[i].size(); j++)
                    ans += tree[i][0] + tree[i][j];
            }
        }
        printf("%lld\n", ans);
    }
}