最小生成树的普里姆算法c实现


/*
算法概述:假设N=(V,E)是连通图 ,TE是N上的最小生成树中的边集合。算法从定点
集合U={u0}(u0属于v),边集合TE开始为空,在u属于集合U,v 属于集合V-U的边(u,v)属于
E中找一条代价最小边 
*/

#include
< stdio.h >
#include
< limits.h >
#define  MAXN 1002
typedef 
struct   {
    
int Vnum;
    
int Arcs[MAXN][MAXN];
    }
Graph;
Graph g;
int  tree[ 1003 ][ 4 ];
void  create_graph( int  vn, int  en) {
        
int i,j,n;
        
int v1,v2,w;
        g.Vnum
=vn;
        
for(i=1;i<=vn;i++)
            
for(j=1;j<=vn;j++)
                 g.Arcs[i][j]
=INT_MAX;
          
for(i=1;i<=en;i++)
                
{
                    scanf(
"%d%d%d",&v1,&v2,&w);
                    
//if(e[a][b]<INT_MAX && e[a][b]<c)continue;
      g.Arcs[v1][v2]=g.Arcs[v2][v1]=w;
                }

    }
 
void  prim() {
    
int i,j,k,m,min,c,vn;
    
int V[MAXN],lowcost[MAXN];
    vn
=g.Vnum;
     
for(i=1;i<=vn;i++){
             V[i]
=1;//设初始为1表示 tree中开始只有点1 
   lowcost[i]=g.Arcs[1][i];//i到V[i]的权值 
  
            }

  V[
1]=0;//点1不再是要考虑的点 
     for(i=1;i<vn;i++)
     
{
        min
=INT_MAX;
  
for(m=1;m<=vn;m++)
    
if(V[m]!=0&&lowcost[m]<min)
                

                    min
=lowcost[m];
                    k
=m;
            }

        tree[i][
1]=V[k];
        tree[i][
2]=k;
        tree[i][
3]=min;
        
        V[k]
=0;//点k不再是要考虑的点 
        for(j=1;j<=vn;j++)//由于tree新加入k点,试图找出tree中点到非tree中点更小的权值 
            if(V[j]!=0 && g.Arcs[k][j]<INT_MAX && g.Arcs[k][j]<lowcost[j]){
                    lowcost[j]
=g.Arcs[k][j];
                    V[j]
=k;
                }

    }

}

int  main() {
        
int vn,en,value,i,j;
        
while(scanf("%d%d",&vn,&en)!=EOF)
        
{
            create_graph(vn,en);
            prim();
            
for(j=1;j<vn;j++)
                printf(
"%d %d %d ",tree[j][1],tree[j][2],tree[j][3]);
        
            }

    
}

/*
Input:
6 10
1 2 6
1 3 1
1 4 5
2 3 5
2 5 3
3 4 5
3 5 6
3 6 4
4 6 2
5 6 6
Output:
1 3 1
3 6 4
6 4 2
3 2 5
2 5 3
*/
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值