You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# include <bits/stdc++.h>
using namespace std ;
const int N = 310 ;
int n ; // n条顶点
int res ; // 最小生成树的权值和
// Kruskal用到的结构体
const int M = 2 * N * N ; // 无向图*2, 稠密图N*N
struct Edge {
int a , b , c ;
const bool operator < ( const Edge & t ) const {
return c < t . c ;
}
} edge [ M ] ;
int el ; // 边数
// 并查集
int p [ N ] ;
int find ( int x ) {
if ( p [ x ] ! = x ) p [ x ] = find ( p [ x ] ) ;
return p [ x ] ;
}
// Kruskal算法
int kruskal ( ) {
// 按边的权重排序
sort ( edge , edge + el ) ;
// 初始化并查集,注意并查集的初始是从0开始的, 因为0号是超级源点
for ( int i = 0 ; i < = n ; i + + ) p [ i ] = i ;
// 枚举每条边
for ( int i = 0 ; i < el ; i + + ) {
int a = edge [ i ] . a , b = edge [ i ] . b , c = edge [ i ] . c ;
a = find ( a ) , b = find ( b ) ;
if ( a ! = b )
p [ a ] = b , res + = c ;
}
return res ;
}
int main ( ) {
cin > > n ;
// 建立超级源点(0 <-> 1~n )
int c ;
for ( int i = 1 ; i < = n ; i + + ) {
cin > > c ; // 点权转边权
edge [ el + + ] = { 0 , i , c } ;
edge [ el + + ] = { i , 0 , c } ;
}
// 本题是按矩阵读入的, 不是按a,b,c方式读入的
for ( int i = 1 ; i < = n ; i + + )
for ( int j = 1 ; j < = n ; j + + ) {
cin > > c ;
edge [ el + + ] = { i , j , c } ;
edge [ el + + ] = { j , i , c } ;
}
// 利用Kruskal计算最小生成树
cout < < kruskal ( ) < < endl ;
return 0 ;
}