题意:有一棵边带有权值的树,定义线图:将这颗树的每一条边缩成一个点,这个点的点权为原先的边权,当原先树中两条边有公用的节点时,则线图中缩成的两个点有边相连,且边的权值为这两个点的点权之和。求形成的线图的最小生成树。

解题思路:你会发现在原先的树中,父节点和他紧邻的所有子节点形成的线图是一个完全图,而这个完全图的最小生成树只需将其他点和点权最小的点连接起来就可以了。看懂下面这个图就好理解代码了

发下代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>

using namespace std;

#define pi acos(-1.0)
#define e exp(1.0)
typedef long long ll;
const ll maxn=1e5+7;
vector<ll>V[maxn];
ll T,N;
int main()
{
// freopen(".../.txt","w",stdout);
	ios::sync_with_stdio(false);
	cin>>T;
	while(T--)
	{
		cin>>N;
		ll i,j;
		for(i=1;i<=N;i++)
		V[i].clear();
		for(i=1;i<=N-1;i++)
		{
			ll u,v,w;
			cin>>u>>v>>w;
			V[u].push_back(w);
			V[v].push_back(w);
		}
		ll res=0;
		for(i=1;i<=N;i++)
		{
			if(V[i].size()<2)
			continue;
			ll minn=0x3f3f3f3f3f;
			for(j=0;j<V[i].size();j++)
			{
				res+=V[i][j];
				minn=min(minn,V[i][j]);
			}
			res+=(minn*(V[i].size()-2));
		}
		cout<<res<<endl; 
	}
	return 0;
}