Part I:
(1)最小生成树:
在无向连通带权图中,找到权值最小的,连通所有点的非负权线路
(2)Kruskal涉及思想算法:
贪心思想,并查集算法
(3) 令G=(V,E):
G代表无向连通带权图,V为所有顶点,E代表所有边
(4)假设V=7则:图1:
(5)解释负权:
负权即形成回路,图2:
Part I I:讲解算法思路:
(1)目的:
我们要得到所有点的连通路线,则这条线路必定有n-1条边
图3:
(2)贪心思想+并查集的运用:
我们要找到权值最小的线路,我们可以对边的权值进行结构体排序
这里我们用最简单的图来讲解:
图4:
图5:
对于图四来说,G=(3,3),所有有3条边,3个顶点,我们将片的权值排序,得到图五,令线路权值最小权值和为sum,n为边数,权值为val
(1)先将并查集在图中的应用:
最小生成树由于是一条线路,所有所有点连通,即有亲戚关系
最初:
sum=0,n=0
所有点并未连接,都是一个独立的集合,所以我们找到权值最小的边,判断它的两个点是不是一个集合,如果不是sum+=该边的val,n++,如果是就跳过这条边,直到n==V-1,结束操作
为什么是亲戚的时候不能连接:
当我们查到白球和红球的边的时候,因为他们是亲属,我们把他们连接,就构成了回路,而我们的线路不需要回路
Part III(Kruskal)代码:
long long ans=0;
struct node
{
int start,to,val;//一条边上的两端点,和边长
}bian[2000005];
bool cmp(node a,node b)
{
return a.val<b.val;//应用了贪心
}
int parent[100005];
int find(int x)//查
{
if(x!=parent[x])
{
parent[x]=find(parent[x]);
}
return parent[x];
}
int kruskal(int n,int m)
{ int toal=0;
for(int i=1;i<=m;i++)//m条边
{
int boss1=find(bian[i].start);//每条边上的连个端点
int boss2=find(bian[i].to);
if(boss1==boss2)
continue;
ans+=bian[i].val;
parent[boss2]=boss1;//合并
toal++;
if(toal==n-1)
return 1;
}
if(toal!=n-1)
return 0;
}