这道题是长春的E题,我是看了别人才会做的,这道题是一个并查集的题,将边按从大到小排序,然后依次合并,
这样每次都是按边的权值来计算合并后的值,接下来就是讨论这两个集合谁并入谁,应该是合并后所得值小的
并入值大的,这样就要记录每个集合当前元素个数sum和当前值rank
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std ;
const int MAXN = 200005 ;
int N ;
struct Edge
{
int start , end ;
int w ;
} ;
Edge edge[MAXN] ;
long long father[MAXN] , rank[MAXN] , sum[MAXN] ;
bool cmp( Edge a , Edge b )
{
return a.w > b.w ;
}
int find( int x )
{
if( father[x] == x ) return x ;
father[x] = find( father[x] ) ;
return father[x] ;
}
int main()
{
int i , j ;
while( scanf( "%d" , & N ) != EOF )
{
memset( rank , 0 , sizeof( rank ) ) ;
//memset( sum , 1 , sizeof( sum ) ) ;
for( i = 1 ; i <= N ; i ++ )
{
father[i] = i ;
sum[i] = 1 ;
}
for( i = 1 ; i < N ; i ++ )
scanf( "%d%d%d" , & edge[i].start , & edge[i].end , & edge[i].w ) ;
sort( edge + 1 , edge + N , cmp ) ;
for( i = 1 ; i < N ; i ++ )
{
int x = find( edge[i].start ) ;
int y = find( edge[i].end ) ;
long long tmp1 = ( long long ) sum[x] * edge[i].w + rank[y] ;
long long tmp2 = ( long long ) sum[y] * edge[i].w + rank[x] ;
if( tmp1 > tmp2 )
{
father[x] = y ;
rank[y] = tmp1 ;
sum[y] += sum[x] ;
}
else
{
father[y] = x ;
rank[x] = tmp2 ;
sum[x] += sum[y] ;
}
}
cout << rank[find(1)] << endl ;
}
return 0 ;
}