Kruskal算法实现

原创 2016年06月02日 11:53:38
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <queue>
#define NUM 6
#define MAXSIZE 30
using namespace std;

//定义并查集树
typedef struct UNode
{
     int data;
     int rank;
     int parent;
} UNode,UFSTree;

//定义邻接矩阵
typedef struct Node
{
     int num;
     int data;
} Node;
typedef struct MGraph
{
     int edges[NUM][NUM];
     int n,e;
} MGraph;

//定义边
typedef struct Edge
{
     int u;//起点
     int v;//终点
     int w;//权值

     bool operator < (const Edge &a) const
     {
	  return w > a.w;
     }
} Edge;

MGraph *build_graph();
void kruskal(MGraph *mgraph);
void MAKE_SET(UFSTree t[], int n);
int FIND_SET(UFSTree t[], int x);
void UNION(UFSTree t[], int x, int y);

int main(void )
{
     MGraph *mgraph;

     mgraph=build_graph();
     kruskal(mgraph);
     return 0;
}

MGraph *build_graph()
{
     MGraph *mgraph;
     int i,j;
     int this_edges=0;
     int arrays[NUM][NUM]={{0,6,1,5,INT_MAX,INT_MAX},
			   {6,0,5,INT_MAX,3,INT_MAX},
			   {1,5,0,5,6,4},
			   {5,INT_MAX,5,0,INT_MAX,2},
			   {INT_MAX,3,6,INT_MAX,0,6},
			   {INT_MAX,INT_MAX,4,2,6,0}};
     mgraph=(MGraph *)malloc(sizeof(MGraph));
     for(i=0;i<NUM;i++)
     {
	  for(j=0;j<NUM;j++)
	  {
	       mgraph->edges[i][j]=arrays[i][j];
	       if(arrays[i][j]!=0 && arrays[i][j]!=INT_MAX)
	       {
		    this_edges++;
	       }
	  }
     }
     mgraph->n=NUM;
     mgraph->e=this_edges;

     //测试生成的邻接矩阵
     printf("node=%d,edges=%d\n",mgraph->n,mgraph->e);
     for(i=0;i<NUM;i++)
     {
	  for(j=0;j<NUM;j++)
	  {
	       if(mgraph->edges[i][j]!=INT_MAX)
	       {
		    printf("%3d",mgraph->edges[i][j]);
	       }
	       else
	       {
		    printf("%3c",'&');
	       }
	  }
	  printf("\n");
     }
     
     return mgraph;
}

//Kruskal算法
void kruskal(MGraph *mgraph)
{
     int i,j;
     int k;			// 存储已并入的边数
     int u1,v1;			// 存储当前最小边
     int sn1,sn2;		// 存储两个顶点所属集合
     UFSTree t[MAXSIZE];	// 存储并查集树
     Edge E[MAXSIZE];		// 存储所有的边
     priority_queue<Edge> pq;	// 优先队列,每次弹出最小边

     //把所有边存入优先队列
     k=1;
     for(i=0;i<mgraph->n;i++)
     {
	  for(j=0;j<=i;j++)
	  {
	       if(mgraph->edges[i][j]!=0 && mgraph->edges[i][j]!=INT_MAX)
	       {
		    E[k].u=i;
		    E[k].v=j;
		    E[k].w=mgraph->edges[i][j];
		    pq.push(E[k]);
	       }
	  }
     }

     MAKE_SET(t,mgraph->n);	// 初始化并查集

     //每次选出最小边并入
     k=1;
     while(k<mgraph->n)
     {
	  u1=pq.top().u;
	  v1=pq.top().v;

	  sn1=FIND_SET(t,u1);
	  sn2=FIND_SET(t,v1);
	  if(sn1!=sn2)
	  {
	       printf("%d-%d: %d\n",u1,v1,pq.top().w);
	       k++;
	       UNION(t,u1,v1);
	  }
	  pq.pop();
     }
     
}

//初始化并查集
void MAKE_SET(UFSTree t[], int n)
{
     int i;
     for(i=0;i<n;i++)
     {
	  t[i].data=i;
	  t[i].rank=0;
	  t[i].parent=i;
     }
}
//并查集查找
int FIND_SET(UFSTree t[], int x)
{
     if(x!=t[x].parent)
	  return FIND_SET(t,t[x].parent);
     else
	  return x;
}
//并查集合并
void UNION(UFSTree t[], int x, int y)
{
     x=FIND_SET(t,x);
     y=FIND_SET(t,y);

     if(t[x].rank > t[y].rank)
	  t[y].parent=x;
     else
     {
	  t[x].parent=y;
	  if(t[x].parent==t[y].parent)
	       t[y].rank++;
     }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Kruskal算法python实现

最小生成树之Kruskal算法实现

最小生成树kruskal算法实现

Kruskal算法的实现

HDOJ 1863畅通工程(最小生成树kruskal算法并查集实现)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1863 最小生成树kruskal算法:http://www.zhuoda.org/irini/78592....

数据结构之图---最小生成树Kruskal算法---C++实现

一、需求图Kruskal算法最小生成树 无向图中点与点之间,边上的数字表示权值。 二、实现Kruskal算法最小生成树 1.边的描述 定义边的对象时应有以下属性:这条边连接两端的点(nodeIn...

nyoj118次小生成树,由kruskal算法实现

修路方案 时间限制:3000 ms  |  内存限制:65535 KB 难度:5 描述 南将军率领着许多部队,它们分别驻扎在N个不同的城市里,这些城市分别编号1~N,由于交通不太便利...

Kruskal算法C语言实现

#include #include #include #include #define MAX 100 // 矩阵最大容量 #define INF...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)