#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;
}
24.kruskal算法 求 最小生成树
最新推荐文章于 2021-07-05 16:50:32 发布