求图的最小生成树的prime算法和Kruskal算法

来源:互联网 发布:python for none 编辑:程序博客网 时间:2024/06/06 00:34

prime算法原理

1.首先清空树,任取一个顶点加入生成树。

2.在那些一个顶点在生成树李,另一个顶点不在生成树里德边中,选取边权最小的一条边,把这条边的另一个顶点加入生成树。

3.重复步骤2,直到所有的顶点均加入了生成树。

如图所示:


代码:

int map[max][max];int vis[max];int d[max];int prime(){int sum=0;int index=1; //先将顶点1加入生成树vis[1]=1;    //标记顶点1    for(int i=0;i<m;i++)  //将与顶点1相连的边的权值赋给d数组    {    d[i]=map[index][i];    }    for(int i=1;i<m;i++)    {    int min=MAX;  //MAX为定义的无穷大    for(int j=0;j<m;j++) //找边权最小值    {    if(!vis[j] && d[j]<min)    {    min=d[j];    index=j;    }    }    vis[index]=1;//标记掉(把index加入生成树)    sum+=min;    for(int j=0;j<m;j++)//更新边权    {          if(!vis[j] && d[j]>map[index][j])          d[j]=map[index][j];    }    }    return sum;}int main(){/*要在主函数中先将map数组定义为无穷大,将vis数组清空,然后在输入顶点与边权*/for(int i=0;i<max;i++){for(int j=0;j<max;j++){map[i][j]=MAX;}}memset(vis,0,sizeof(vis));}

Kruskal算法

原理:先将子图看成一个只含有n个顶点的不含边的图,各个顶点看成是各自树的根节点。

从边集中选取一条权值最小的边,判断该边的两个顶点是否分属不同的树,若是则将其加入子图,然后将这两个顶点分别所在的树合成一棵树;若不是,则说明这两个点已在一颗树上,不可取。(用到了并查集)

代码:

int father[max];int rank[max];struct node{//将边的边权、起点、终点int val,start,end;}edge[边的最多的条数];void make()//初始化{for(int i=0;i<n;i++){father[i]=i;rank[i]=1;}}int find(int x)//找根节点{int i,j=x;while(j!=father[j]){j=father[j];}while(x!=j){i=father[x];father[x]=j;x=i;}return j;}void union(int x,int y){x=find(x);y=find(y);if(x==y)return;if(rank[x]<rank[y])//合并{father[x]=find(y);}else{if(rank[x]==rank[y]){rank[x]++;}father[y]=find(x);}}int Kruskal(int n){int sum=0;make();for(int i=0;i<n;i++)//从边权最小的边开始加入图中{if(find(edge[i].start)!=find(edge[i].end)){union(edge[i].start,edge[i].end);sum+=edge[i].val;}}return sum;}bool cmp(node a,node b){return a.val<b.val;}int main(){//输入边的边权,起点,终点//在主函数内将边按边权从小到大排序sort(edge,edge+边的条数,cmp);int ans=Kruskal(n);//n为边的数量}


0 0
原创粉丝点击