题目:
分析:最小生成树就两种方法。
提醒一个要点,因为是树,所以可能以点计数,也可能以边计数。
Kruskal(克鲁斯卡尔)~边:
1.边排序。
2.按顺序加入并判断不能成环,以并查集来判断。
首先使用结构体+cmp:
#include <bits/stdc++.h>
using namespace std;
int m, n;
struct edge{
int start, end;
int len;
} ;
bool cmp ( edge a, edge b)
{
return a. len> b. len;
}
vector< edge> v;
int main ( )
{
cin>> m>> n;
for ( int i= 0 ; i< n; i++ )
{
int a, b, c;
cin>> a>> b>> c;
struct edge e;
e. start= a;
e. end= b;
e. len= c;
v. push_back ( e) ;
}
sort ( v. begin ( ) , v. end ( ) , cmp) ;
for ( int i= 0 ; i< v. size ( ) ; i++ )
{
cout<< v[ i] . len<< ' ' ;
}
}
加入并查集来判断,新的边是否可以加入。
和题解差不多,竟然有错???一脸冥币:
#include <bits/stdc++.h>
using namespace std;
int m, n;
int fa[ 5005 ] ;
struct edge{
int start, end;
long long len;
} v[ 200005 ] ;
bool cmp ( edge a, edge b)
{
return a. len< b. len;
}
int find ( int x)
{
if ( fa[ x] == x) return x;
fa[ x] = find ( fa[ x] ) ;
return fa[ x] ;
}
int main ( )
{
cin>> m>> n;
for ( int i= 0 ; i< n; i++ )
{
int a, b, c;
cin>> a>> b>> c;
v[ i] . start= a;
v[ i] . end= b;
v[ i] . len= c;
}
sort ( v, v+ n, cmp) ;
for ( int i= 1 ; i<= m; i++ ) fa[ i] = i;
int num= 0 ;
int ans= 0 ;
for ( int i= 0 ; i< n; i++ )
{
if ( find ( v[ i] . start) == find ( v[ i] . end) ) continue ;
num++ ;
fa[ find ( v[ i] . start) ] = find ( v[ i] . end) ;
ans+ = v[ i] . len;
if ( num+ 1 == m) break ;
}
cout<< ans;
}
第二种方法,从一个点出发。
我觉得自己的代码思路很好。代码写的也非常的简练,很好
思路:
和地杰斯特拉算法差不多:
1.以一个集合来存放已经确定的点。
2.首先加入一个点,然后该点的边全部加入队列。
3.取出队列首个,如果两个点都加入,取下一个。
只有一个加入,则改变确定,另一个点确定,另一个点加入到确定点集合,并且该点所有的边加入到队列。(可以优化的一步是:加入的边的另一个点未加入已确定点集合才有必要加入队列)
ac代码:
#include <bits/stdc++.h>
using namespace std;
int m, n;
struct node{
int e1;
int e2;
int len;
bool operator < ( const node & x) const
{
return x. len< len;
}
} ;
priority_queue< node> q;
vector< vector< node> > vvn;
set< int > s;
int ans= 0 ;
int main ( )
{
cin>> m>> n;
vector< node> vn;
for ( int i= 0 ; i<= m; i++ ) vvn. push_back ( vn) ;
for ( int i= 0 ; i< n; i++ )
{
int a, b, c;
cin>> a>> b>> c;
struct node nn;
nn. e1= a;
nn. e2= b;
nn. len= c;
vvn[ a] . push_back ( nn) ;
vvn[ b] . push_back ( nn) ;
}
s. insert ( 1 ) ;
for ( int i= 0 ; i< vvn[ 1 ] . size ( ) ; i++ )
{
q. push ( vvn[ 1 ] [ i] ) ;
}
while ( s. size ( ) != m)
{
struct node nn= q. top ( ) ;
q. pop ( ) ;
if ( s. count ( nn. e1) == 1 && s. count ( nn. e2) == 1 ) continue ;
ans+ = nn. len;
int c;
if ( s. count ( nn. e1) == 1 ) c= nn. e2;
else c= nn. e1;
s. insert ( nn. e1) ;
s. insert ( nn. e2) ;
for ( int i= 0 ; i< vvn[ c] . size ( ) ; i++ )
{
if ( s. count ( vvn[ c] [ i] . e1) && s. count ( vvn[ c] [ i] . e2) ) continue ;
q. push ( vvn[ c] [ i] ) ;
}
}
cout<< ans;
}