24.kruskal算法 求 最小生成树


#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<queue>
#include<stack>
#define OK 0
#define ERROR 1
#define MAXSIZE 1000
using namespace std;
typedef int ElemType;
FILE *fp;
void InitFile()
{
	bool e;
	fopen_s(&fp, "data.txt", "r");
	if (!fp) exit(ERROR);
	return;
}
typedef bool Status;


  Kruskal算法  生成最小生成树
/******
file input:
5
1 2 3
2 3 4
4 5 6 
2 4 3
5 2 8
1 4 1
3 5 7
1 5 2
0 0 0//8组数据
*******/



/*typedef struct node
{
	int vertex;
	struct node *link;

}Node, *node_ptr;*/

//node_ptr vertex;

int ver_num;
int vertex[MAXSIZE];

typedef struct edge
{
	int v1,v2;
	int weight;
}Edge,*Edge_ptr;


Edge_ptr G_Edge[MAXSIZE];
int G_Edge_n;

void insert_edge_minheap(Edge_ptr c,int &n)
{
	int i;
	Edge_ptr t;
	int k = ++n;
	while (k>1)
	{
		if (c->weight < G_Edge[k / 2]->weight)
		{
			G_Edge[k] = G_Edge[k / 2];
			k /= 2;
		}
		else break;
	}
	G_Edge[k] = c;
}

void delete_edge_minheap(Edge_ptr &c, int &n)
{
	if (!n) { c = NULL; return; };
	Edge_ptr t;
	int p;
	c = G_Edge[1];
	G_Edge[1] = G_Edge[n--];
	int parent = 1,child=2;
	p = 1;
	while(1)
	{
		child = parent * 2;
		if (child <= n)
		{
			p = G_Edge[parent]->weight < G_Edge[child]->weight ? parent : child;
		}
		if (child + 1 <= n)
		{
			p = G_Edge[p]->weight < G_Edge[child+1]->weight ? p : child+1;

		}
		if (p == parent) break;
		else
		{
			t = G_Edge[parent];		G_Edge[parent] = G_Edge[p];		G_Edge[p] = t;
			parent = p;
		}
	}
}
int find(int t)
{
	if (t == vertex[t]) return t;
	else return find(vertex[t]);
}
int is_in(int a, int b)
{
	return find(a) == find(b);// true 则表示 a 已经在一个集合里了
}
int union_v(int a, int b)
{
	if (is_in(a,b)) return 0;//两个点本来就在一个结合里面
	int x = find(a), y = find(b);
	 vertex[x] = y; 
	 return 1;//通过一条边 将两个集合 合并为一个集合
}
stack<Edge> S;
//by zhaoyang @ 2014.4.20
int main()
{
	InitFile();
	G_Edge_n = 0;
	int a, b, w;
	fscanf_s(fp, "%d", &ver_num);
	while (fscanf_s(fp, "%d %d %d", &a, &b, &w)  && a && b && w)
	{
		Edge_ptr t;
		if (!( t= (Edge_ptr)malloc(sizeof(Edge)))) exit(ERROR);
		t->v1 = a; t->v2 = b; t->weight = w;
		insert_edge_minheap(t, G_Edge_n);
	}
	
	Edge_ptr t;//测试 最小堆
	/*while (1)
	{
		t = NULL;
		delete_edge_minheap(t, G_Edge_n);
		if (!t) break;
		printf("%d %d %d\n", t->v1, t->v2, t->weight );
	}*/
	for (int i = 1; i <= ver_num; i++)  vertex[i] = i;

	int num = 0;
	while (num < ver_num-1 )
	{
		delete_edge_minheap(t, G_Edge_n);	if (!t) break;
		if (is_in(t->v1, t->v2)) continue;
		union_v(t->v1, t->v2);
		num++;
		S.push(*t);
	}
	Edge tt;
	if (num == ver_num - 1)
	{
		printf("找到最小生成树啦!!!!!!\n");
		while (!S.empty())
		{
			tt = S.top(); S.pop();
			printf("%d %d %d\n", tt.v1, tt.v2, tt.weight);
		}
		
	}
	else printf("Kruskal 最小生成树 未找到  -.-");;
	
	printf("\nby zhaoyang @ 2014.4.20.\n");

	fclose(fp);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值