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]; } }