克鲁斯卡尔(Kruskal)算法思想:最开始所有的点都属于独立的点集,对所存边的权值从小到大进行排序,每次挑选较短的边连接起来,已连接的点归入已选点集,已选点集中的点不能再进行连接,否则形成环!(并查集判断两点是否属于一个集合)
克鲁斯卡尔算法特点:
1、维护的是边-----边
2、适用于稀疏图
代码实现:
#includeiostream#includecstring#includealgorithm#defineNusingnamespacestd;//定义边structEdge{//a------binta;intb;intc;//权值};Edgeat[N];//把所有边存入数组当中intn,m;//n个顶点,m条边intparent[N];//维护上下级关系//因为需要对权值进行比较排序,所以需要定义比较策略boolcmp(Edgex,Edgey){returnx.cy.c;//从小到大的顺序排序}//查找节点的根,找掌门intfind(intx){intt=x;while(parent[t]!=-1){t=parent[t];}returnt;}intmain(){cinnm;memset(parent,-1,sizeof(parent));for(inti=0;im;i++){cinat[i].aat[i].bat[i].c;}//对所有边进行排序sort(at,at+m,cmp);//cmp是我们提前写好的排序策略intr=0;//存储权值之和for(inti=0;im;i++){intx=find(at[i].a);inty=find(at[i].b);if(x!=y){//如果两个节点不在一个集合才允许连线,否则不允许,会出现环parent[x]=y;r+=at[i].c;}}coutrendl;return0;}
测试结果:
一只小跃跃