并查集kruskal最小生成树
来自刘汝佳《算法竞赛入门经典》
- 这里判断是否在一个集合中不要一上来就set<>,用边数组和对应此边两端的节点,加上节点的并查集就能很好的解决问题。
- 注意r[]排序数组的作用,cmp用w[]作为依据,对r[]中的元素进行排序。
#include<bits/stdc++.h>
using namespace std;
const int n=100,m=10; //n nodes m edges
int u[n],v[n]; //number of the i-th edge's source and destination
int w[m]; //the i-th edge's weight
int p[n]; //the i-th node's root(father)
int r[m]; //sorted by weight of all edges
int cmp(int i,int j){return w[i]<w[j];}
int findf(int i){while(p[i] != i) i=p[i];}
int main()
{
int ans = 0;
for(int i=0;i<n;++i) p[i]=i;
for(int i=0;i<m;++i) r[i]=i;
//array r is used to get a sorted-weight number of the edges,use the cmp func to get
//this
sort(r,r+m);
for(int i=0;i<m;++i)
{
int a=findf(u[r[i]]),b=findf(v[r[i]]);
if(a!=b){ans+w[i];p[a]=b;}
}
return ans;
}