写给自己看而已
有两种算法(关于这两个算法的名字没必要纠结。。。中文翻译出来叫啥都有)
1.普里姆算法(时间复杂度n2(n为点的数量))
思路:随便找一个点A,找到这个点A连接其他点B的最小的边(现在默认已经连上两个点了),将这两个点作为一个点A来看(跟其他点C连接的举例取两个点跟点C的最小值,一个for循环可实现)。
for循环处理所有的点,直到所有点连接上我们就能找到最小生成树
2.克鲁斯卡算法(时间复杂度n*logn (n为边的数量))
思路:先对所有边进行排序,取一个最小的边,连接最小的边的两个点,在取一个第二小的边,连接第二小的边上的两个点(注意不要形成环,否则就不是树了)
这两种算法的时间复杂度一个是针对边来计算一个是针对点来计算所以具体情况具体分析
附克鲁斯卡算法代码
#include<iostream>
using namespace std;
struct Edge
{
int nStart;
int nEnd;
int nValue;
};
void MySort(Edge *ArrEdge,int nLeft,int nRight)
{
if (nLeft >= nRight)
{
return;
}
int i = nLeft;
int j = nRight;
int nTemp_Value = ArrEdge[nLeft].nValue;
int nTemp_Start = ArrEdge[nLeft].nStart;
int nTemp_End = ArrEdge[nLeft].nEnd;
while (i < j)
{
while (i < j && ArrEdge[j].nValue >= nTemp_Value)
{
j--;
}
if (i < j)
{
ArrEdge[i].nValue = ArrEdge[j].nValue;
ArrEdge[i].nStart = ArrEdge[j].nStart;
ArrEdge[i++].nEnd = ArrEdge[j].nEnd;
}
while (i < j && ArrEdge[j].nValue <= nTemp_Value)
{
i++;
}
if (i < j)
{
ArrEdge[j].nValue = ArrEdge[i].nValue;
ArrEdge[j].nStart = ArrEdge[j].nStart;
ArrEdge[j--].nEnd = ArrEdge[j].nEnd;
}
}
ArrEdge[i].nValue = nTemp_Value;
ArrEdge[i].nStart = nTemp_Start;
ArrEdge[i].nEnd = nTemp_End;
MySort(ArrEdge,nLeft,i);
MySort(ArrEdge, i + 1, nRight);
}
int FindParent(int *Parent, int nStart)
{
while (nStart != Parent[nStart])
{
nStart = Parent[nStart];
}
return nStart;
}
int main()
{
int n, m;//n为点的个数,m为边的个数
while (cin >> n >> m)
{
Edge *vArrEdge = new Edge[m];
int *Parent = new int[n];
bool bFlag = false;
int nAns = 0;
int nEdgeCount = 0;
for (int i = 0; i < m; i++)
{
int nTemp_Start,nTemp_End,nTemp_Value;
cin >> vArrEdge[i].nStart >> vArrEdge[i].nEnd >> vArrEdge[i].nValue;
vArrEdge[i].nStart--;
vArrEdge[i].nEnd--;
}
MySort(vArrEdge, 0, m-1);
for (int i = 0; i < n; i++)
{
Parent[i] = i;
}
for (int i = 0; i < m; i++)
{
int nTemp_Start = FindParent(Parent, vArrEdge[i].nStart);
int nTemp_End = FindParent(Parent, vArrEdge[i].nEnd);
if (nTemp_Start != nTemp_End)
{
Parent[nTemp_Start] = nTemp_End;
nAns += vArrEdge[i].nValue;
nEdgeCount++;
}
if (nEdgeCount == n - 1)
{
bFlag = true;
break;
}
}
if (bFlag)
{
cout << nAns << endl;
}
else
{
cout << "-1" << endl;
}
delete[] vArrEdge;
delete[] Parent;
}
return 0;
}