东北四省赛E-Minimum Spanning Tree-贡献求和

这篇博客介绍如何利用数学概念和算法在给定树G的基础上,找到其线图L(G)的最小生成树(MST),并提供了一个程序实例来计算所有边的总权重。通过理解两个图之间的关系和MST的概念,读者将学会如何高效地解决这类图论问题。
摘要由CSDN通过智能技术生成

题目描述:

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

Precisely speaking, for an undirected weighted graph G without loops or multiple edges, its line graph L(G) is a graph such that:

  1. Each vertex of L(G) represents an edge of G.
  2. Two vertices of L(G) are adjacent if and only if their corresponding edges share a common endpoint in G, 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 tree G, please write a program to find the minimum spanning tree of L(G).

输入描述:

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

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

For the next n−1 lines, each line contains three integers u,v,w(1≤u,v≤n,u≠v,1≤w≤109), denoting a bidirectional edge between vertex u and v with weight w.

It is guaranteed that ∑n≤106.

输出描述:

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

输入样例:

2
4
1 2 1
2 3 2
3 4 3
4
1 2 1
1 3 1
1 4 1

输出样例:

8
4

大概思路:

在图G中,对某个有m条边的结点i而言,可以贡献给L(G)的边数为m*(m-1)/2,而对于MST(L(G)),结点i的最小临边贡献m-1次,其他m-1条边各贡献一次。详见代码。

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e5+20;
ll a[N],c[N];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n,u,v;
		ll w,sum=0;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
		{
			a[i]=1e10;
			c[i]=0;
		}
		for(int i=1;i<n;i++)
		{
			scanf("%d%d%lld",&u,&v,&w);
			sum+=w<<1;
			c[u]++;
			c[v]++;
			a[u]=min(a[u],w);
			a[v]=min(a[v],w);
		}
		for(int i=1;i<=n;i++)
			sum+=a[i]*(c[i]-2);
		printf("%lld\n",sum);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值