東北四省賽E-Minimum Spanning Tree-貢獻求和
技術標籤:思維圖論MinSpanningTree東北省賽貢獻
題目描述:
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:
- Each vertex of L(G) represents an edge of G.
- 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;
}