最小生成树——Kruskal算法 和 Prim算法

prim算法适合稠密图

kruskal算法适合稀疏图


Prim算法模板
lowcost[i]存储点i和它父亲结点的权值,closest[k]数组记录点k的父亲结点

void Prim(int v)//v为初始点,可以是n个点中的任意一个
{
    int i,j,k;
    
    for(i=0;i<n;i++) lowcost[i]=(i==v ? 0 :INF); 
    
    for(i=0;i<n;i++)//找出n-1条边
    {
        int min=INF;//初始化min为一个很大的值
        
        for(j=0;j<n;j++)//从所有为标号结点中,选出lowcost最小的结点k
        {
            if(lowcost[j]&&lowcost[j]<=min) min=lowcost[k=j];//最终找到的点的序号赋给k
        }
        
        printf("%d %d\n",k,closest[k] );//打印选择的边,和它的父亲结点
        
        lowcost[k]=0;//标记k点为已经被选了


        for(j=0;j<n;j++)
        {
            if(lowcost[j]&&g[k][j]<lowcost[j])//对于从k出发的所有边(k,j),更新lowcost[j]=min(lowcost[j],g[k][j]);
            {
                lowcost[j]=g[k][j];
                closest[j]=k;//使得点j的父亲为k
            }
        }
    }
}


Kruskal算法模板
贪婪思想
1.将边的权值从小到大进行排序
2.选择小的权值的边,如果是左右端点是连通的,则跳到下一条,否则把该条边选进来,使得左右端点连通
3.直到所有的点都是连通的

struct node
{
    int u,v,w;
}e[A];//定义结构体e,来存放每条边的左端点u,右端点v,权值w
int f[MAX];


int find(int x)
{
    return f[x]==x ? x : f[x]=find(f[x]);//寻找点x的根结点,同时进行路径压缩
}


void Union_set(int x,int y,int w)//判断根节点x,y是否相同,相同则它们是连通的,不进行处理,否则使它们连通
{
    if(x!=y)
    {
        f[x]=y;
    }
}


bool cmp(node x,node y)
{
    return x.w<y.w;//将边的权值从小到大进行排序
}



你可能感兴趣的:(最小生成树——Kruskal算法 和 Prim算法)