先上比葫芦画瓢的代码
#include<iostream>
using namespace std;
struct edge
{
int u;
int v;
int w;
}e[1001];
int sum = 0;
int all = 0;
int n,m;
int f[9]={0};
void quicksort(int left,int right)
{
int i,j;
struct edge t;
if(left > right)
{
return ;
}
i=left;
j=right;
while(i != j)
{
//从右边开始找
while(e[j].w>=e[left].w && i<j)
{
j--;
}
//从左面开始
while(e[i].w <= e[left].w && i<j)
{
i++;
}
//交换
if(i<j)
{
t=e[i];
e[i]=e[j];
e[j]=t;
}
}
//最终将基准数归位,将left和i交换
t=e[left];
e[left]=e[i];
e[i]=t;
quicksort(left,i-1);//处理左边
quicksort(i+1,right);//处理右边
return ;
}
int find(int v)
{
if(f[v] == v)
{
return v;
}
else
{
f[v]=find(f[v]);
return f[v];
}
}
void join( int v,int u)
{
int t1,t2;
t1=find(v);
t2=find(u);
if(t1 != t2)
{
f[t2]=t1;
}
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
cin>>e[i].u;
cin>>e[i].v;
cin>>e[i].w;
}
quicksort(1,m);
for(int i=1;i<=n;i++)
{
f[i] = i;
}
for(int i=1;i<=m;i++)
{
int fa = find(e[i].u);
int fb = find(e[i].v);
if(fa == fb) continue;
join(e[i].u,e[i].v);
all ++;
sum += e[i].w;
cout << i << endl;
if(all == n-1)
{
break;
}
}
cout<<all<<endl;
cout<<sum<<endl;
return 0;
}
kruskal是以边为判断基准,节点是用来判断该边是否具有作为树的一部分的价值。
1,输入之类的就不说了,n个顶点,m条边。用结构体来实现,储存边的长度,两边顶点的要求。
2,对所有的边长度进行排序。
3,将没有包含在树中的顶点利用最短边引入树
4,不断重复3步。由于只引入未联通的顶点,所以当引入n-1次的话,所有的点就联通了。
关于引入部分的注意
1 引入的关键是判断是不是已经联通的顶点。
对于所有边按升序遍历,判断该边的两个顶点是否通过其他途径已经联通。
我所学的方法是利用并查集查找祖节点来实现的。
2 判断该节点已经在树中的话,该边遍历过不作处理。
3 该边两个节点没有通过其他途径连接的话,就将该边变为树的一部分,并将两个节点变为同一个祖先。