图论(最小生成树,Prim算法和Kruskal算法)

20 篇文章 0 订阅
17 篇文章 0 订阅

#include<stdio.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;

#define maxSize 101

int INF = -2313;
int MINF = 6666;//定义图的图的无穷大量

typedef struct MGraph
{
    int n,e;
    int edges[maxSize][maxSize];
};


//邻接表
typedef struct ArcNode
{
    int adjvex;//该点所指顶点的位置信息

    ArcNode *nextarc;//指向下一条边
} ArcNode;

typedef struct
{

    int data;
    int count;//统计入度信息
    ArcNode *firstarc;//指向第一条边


} VNode,AdjList;

typedef struct AGraph
{
    AdjList adjlist[maxSize];

    int n,e;

} AGraph;

int visit[1001];


//邻接矩阵转化为邻接表
void creatAGraph(AGraph *G,MGraph M)
{

    G->e = M.e;
    G->n = M.n;



    for(int i=0; i<M.n; i++) //构造顶点表
    {
        G->adjlist[i].data = i;
        G->adjlist[i].firstarc = NULL;
        G->adjlist[i].count = 0;
    }


    ArcNode *p;



    for(int i=0; i<M.n; i++) //头插法来构造
    {
        for(int j=0; j<M.n; j++)
            if(M.edges[i][j]!=0)//当存在边的时候采用头插法来构造
            {
                p = (ArcNode*)malloc(sizeof(ArcNode));

                p->adjvex = j;


                p->nextarc = G->adjlist[i].firstarc;


                G->adjlist[i].firstarc = p;


                G->adjlist[j].count++;//对应的入度加1

            }
    }//end for
}


void Visit(int v)
{
    printf("->%d",v);
}

void prim(MGraph M,int v0,int &sum)
{
    int lowCost[maxSize];//定义最下代价数组
    int vset[maxSize],v;//vset为访问标记数组

    int i,j,k,min;


    //初始化
    for(i=0;i<M.n;i++)
    {
        lowCost[i] = M.edges[v0][i];
        vset[i] = 0;
    }
    vset[v0] = 1;//标记第一点访问开始
    sum = 0;

    for(i=0;i<M.n-1;i++)//对剩余n-1个点进行并入最小生成树中
    {
        min = INF;//每次重置我们的最小值

        for(j=0;j<M.n;j++)
            if(vset[j] == 0&&lowCost[j]<min){
                min = lowCost[j];
                k = j;//k用来记录当前最小值的结点
            }

        vset[k] = 1;//将k结点并入最小生成树中
        v = k;
        sum+=min;//计算权值

        //更新我们的lowCost,基于新并入的结点k
        for(j=0;j<M.n;j++)
            if(vset[j] == 0&&M.edges[v][j]<lowCost[j])//当v到j结点路径权值小于当前lowCost则更新我们的lowCost
                lowCost[j] = M.edges[v][j];

    }//end for

}//end prim


int Tree[maxSize];//定义并查集


//并查集
int findRoot(int x)//递归寻找根节点
{
    if(Tree[x] == -1)
        return x;
    else{
        int tmp = findRoot(Tree[x]);
        Tree[x] = tmp;//修改并查集
        return tmp;
    }

}

typedef struct Edge{
    int a,b;
    int weight;
    bool operator <(Edge &A){
        return weight<A.weight;
    }
}edge[5000];

void Kruskal(MGraph M,int &sum,Edge edge[])
{
    int i,a,b;
    sum = 0;
    for(i=0;i<M.n;i++)//设置并查集
        Tree[i] = -1;

    sort(edge,edge+M.e);//进行升序排序

    for(i=0;i<M.e;i++)
    {
        a = findRoot(edge[i].a);
        b = findRoot(edge[i].b);
        if(a!=b)
        {
            Tree[a] = b;
            sum+=edge[i].weight;//将其并入最小生成树中
        }
    }//end for
}//end

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值