这是求无向图的最小生成树的另一算法,主要思想是每次找到一条连接不同连通分量的最小边,然后合并他连接的的这两个连通分量,直至所有的节点构成了一个连通分量(不含通路)~
算法不算难,但是也犯了些很二的错误,在下面写一下吧,当做 参考教训!
参考代码:
#include<iostream>
#include<fstream>
#include<cstring>
#include<algorithm>
using namespace std;
int graph[101][101];
int parent[101];
int node_num;
struct edge
{
int x,y;
int value;
};
edge e0[1001];
edge e1[101];
int edge_num=0;
void garph_to_edge()//这一步其实是多余的,完全可以直接通过edge对图进行直接存储,这里只是为了个人处理方便
{
for(int i=0;i<node_num;i++)
{
for(int j=i+1;j<node_num;j++)
{
if(graph[i][j]<100)
{
e0[edge_num].x=i;
e0[edge_num].y=j;
e0[edge_num].value=graph[i][j];
edge_num++;
}
}
}
}
bool cmp(const edge& ee1,const edge& ee2)
{
return ee1.value<ee2.value;
}
void combine(int i,int j)
{
int count=parent[i]+parent[j];
if(parent[i]>parent[j])
{
parent[i]=j;
parent[j]=count;
}
else
{
parent[j]=i;
parent[i]=count;
}
}
int find(int i)
{
int top=i;
while(parent[top]>-1)
{
top=parent[top];
}
int p=i;
while(p!=top)
{
int temp=parent[p];
parent[p]=top;
p=temp;
}
return top;
}
void kruskal()
{
memset(parent,-1,(node_num+1)*sizeof(int));
sort(e0,e0+edge_num,cmp);
int pointer=0;
int count=0;
while(count<node_num-1)
{
int x=find(e0[pointer].x);
int y=find(e0[pointer].y);
if(x==y)
{
pointer++;
continue;
}
e1[count].x=e0[pointer].x;
e1[count].y=e0[pointer].y;
e1[count].value=e0[pointer].value;
combine(x,y);
count++;
pointer++;
}
for(int i=0;i<node_num-1;i++)
{
cout<<e1[i].x+1<<"\t"<<e1[i].y+1<<"\t"<<e1[i].value<<endl;
}
}
int main()
{
ifstream in;
in.open("graph.txt",ios::in);
in>>node_num;
for(int i=0;i<node_num;i++)
{
for(int j=0;j<node_num;j++)
{
in>>graph[i][j];
}
}
garph_to_edge();
kruskal();
return 0;
}
然后再写一下自己Coding的时候犯的一些二吧:
1.写cmp函数的时候,误把后一ee2写成了ee1,结果排不出来顺序了
2.find函数里排序的时候把sort(e0,e0+edge_num,cmp);开始误写成了sort(e0,e0+edge_num+1,cmp);结果导致增加了后面一组初值为(x,y,0)的成为了第一组,影响了结果!
2.find函数里的第一个循环的判断条件parent[top]>-1原本写成了parent[top]>0。因为之前做的时候都是从下标1开始,所以习惯了写了0,但是这次用的是从0开始,结果可想而知了...
都挺二的,但是还是错了,并且查找的时候还费了好大功夫。也许是真的这学期写的太少了,手生疏了吧,看看还得加油啦!!!