最小生成树模板

Kruskal  

//  类似于并查集 
struct node{
  int st,ed,v; // 起点,重点,权值
  bool operator < (node b) const{     // 相当于cmp
     return v < b.v;
  }
}rod[maxn]; //

int find(int x){ return x == pre[x] ? x : pre[x] = find(pre[x]);} // 并查集的查
bool join(int x,int y){          //并查集的并
    if(find(x)!=find(y)){       
      pre[find(y)] = find(x);
      return true;
    }
    return false;
}

void kruskal(){
  for(int i = 0 ; i <= n; i++){  // 并查集的初始化
    pre[i] = i;
  }
  sort(rod,rod+cnt);  //按权值排序
  for(int i = 0 ;i < cnt ; i++){  
    int mp1 = find(rod[i].st);  
    int mp2 = find(rod[i].ed);
    if(join(mp1,mp2)) ans+= rod[i].v; //连起来
  }
}

prim

// 类似贪心和最短路
void Init(){ // 初始化
  memset(vis,0,sizeof vis);
  ans = 0;
  for(int i = 1 ;i <= n; i++)  dis[i] = inf; //选择的点到其他点的距离
  for(int i = 1 ;i <= n; i++)
    for(int j = 1; j <= n; j++){
      if(i == j)  mapp[i][j] = 0;  
      else mapp[i][j] = inf;
    }
}
void prim(){
  for(int i = 1; i <= n ; i++)
      dis[i]  = mapp[1][i];   //假设从1开始
  dis[1] = 0;
  vis[1] = 1;
  for(int i = 1 ; i < n ; i ++) {
    pos = 1;             
    imin  = inf; //无限大
    for(int j = 1 ; j <= n ; j++ )  
        if(!vis[j]  && dis[j] < imin)  { 
         pos = j , imin = dis[j];     //遍历1周围,找到距离1最短的点,获得下标
        }
    vis[pos] = 1;  //标记已经走过了,避免重复再走
    ans += imin ; //加上权值
    for(int j = 1; j <= n; j++) //更新现在的点到其他未走过的点的最小距离
       if(!vis[j] && mapp[pos][j] < dis[j])   dis[j] = mapp[pos][j];
    }
}
原文地址:https://www.cnblogs.com/llke/p/10780106.html