复习笔记1:用并查集实现 kruskal算法
/**
并查集实现克鲁斯卡尔算法
输入:
6//表示有m条边
1 2 6//表示1和2之间有一条边,权值为6
2 4 1
1 4 2
1 3 1
3 5 4
4 5 3
**/
#include<iostream>
#include<vector>
#include<algorithm>
#define MAX_N 100
using namespace std;
struct Node
{
int numr;
int numd;
int val;
};
int cmp(Node a,Node b)//对vector存储内容进行由小到大排序
{
return a.val<b.val;
}
vector<Node> v;//用vector保存所有边的信息
int F[MAX_N];
/**
找到每个节点的父节点
**/
int findPar(int n)
{
if(F[n]==n)
{
return F[n];
}
else
{
F[n]=findPar(F[n]);//此句比较关键,可以减少下次查找的时间
return F[n];
}
}
/**
如果两个节点不在同一个连通分支中,则合并,并修改其中一棵树根节点的父节点
**/
int merges(int a,int b)
{
int x=findPar(a);
int y=findPar(b);
if(x==y)//相等则表示在同一个连通分支中
{
return 1;
}
else
{
F[y]=x;
return 0;
}
}
int main()
{
for(int i=0;i<MAX_N;i++)
{
F[i]=i;
}
int m;
cin>>m;
for(int i=0;i<m;i++)
{
Node nod;
cin>>nod.numr>>nod.numd>>nod.val;
v.push_back(nod);
}
sort(v.begin(),v.end(),cmp);//根据每条边的权值从小到大排序
for(int i=0;i<v.size();i++)
{
if(!merges(v[i].numr,v[i].numd))
{
v1.push_back(v[i]);
}
}
return 0;
}