最小生成树(prim and kruskal)

最小生成树算法 

比较经典的是这两种 prim   kruskal

思想都是贪心的思想

然而我只会一种...kruskal

这里用到了并查集check关系

先将边权从小到大排序,每次选择没有选择的边中的最小边权,check一下是否会形成环,如果形成环就不选择 否则就选择这条边,就这么做下去...

用邻接表结构来记录边的两个顶点和边权

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=150005;
 7 struct node{
 8     int u, v, cost;
 9 }G[maxn];
10 int a[maxn];
11 void init(int N){
12    for(int i=0; i<N; i++){
13         a[i]=i;
14    }
15 }
16 bool same(int x, int y){
17     return a[x]==a[y];
18 }
19 int Find(int x){
20     return a[x]==x?x:(a[x]=Find(a[x]));
21 }
22 void Merge(int x, int y){
23     x=Find(x);
24     y=Find(y);
25     a[x]=y;
26 }
27 bool cmp(node a, node b){
28     return a.cost<b.cost;
29 }
30 
31 int main(){
32     int n, m;
33     cin>>n>>m;
34     init(n);
35     for(int i=0; i<m; i++){
36         cin>>G[i].u>>G[i].v>>G[i].cost;
37     }
38     sort(G, G+m, cmp);
39     ll ans=0;
40     for(int i=0; i<m; i++){
41         int U=G[i].u, V=G[i].v;
42         U=Find(U), V=Find(V);
43         if(!same(U, V)){
44             Merge(U, V);
45             ans+=G[i].cost;
46         }
47     }
48     cout<<ans<<endl;
49     return 0;
50 }
原文地址:https://www.cnblogs.com/ledoc/p/6560974.html