1. 程式人生 > 實用技巧 >克魯斯卡爾演算法的運用

克魯斯卡爾演算法的運用

  程式碼展示

#define MAX 5000
#include"stdio.h"
#include< stdlib.h >
#pragma warning(disable : 4996)
typedef struct
{
	int fromvex;    /*邊的起始點*/
	int endvex;     /*邊的終止點*/
	int weight;     /*邊的權值*/
}g;
g tree[20] = { 0 }, GE[20] = { 0 }, TREE[20] = { 0 }, t;
int edge[20][20], s[20][20] = { 0 };
int n, m;

void kruskl()
{
	int i, j, k, m1 = 0, m2 = 0, c;
	printf("請輸入頂點數和邊數:");
	scanf("%d%d", &n, &m);
	for (i = 0; i < m; i++)   /*輸入圖的所有邊*/
	{
		printf("按起點,終點和權值依次輸入:");
		scanf("%d%d%d", &GE[i].fromvex, &GE[i].endvex, &GE[i].weight);
	}
	for (i = 1; i < m - 1; i++) /*按邊的權值由小到大直接插入排序*/
	{
		t = GE[i];
		j = i - 1;
		while (j >= 0)
		{
			if (t.weight < GE[j].weight)
			{
				GE[j + 1] = GE[j];
				j = j - 1;
			}
			else
				break;
			GE[j + 1] = t;
		}
	}
	printf("\n排序後的邊與對應的權值\n");
	for (i = 0; i < m; i++)   /*列印排序後的結果*/
		printf("邊:%d->%d權值:%d\n", GE[i].fromvex, GE[i].endvex, GE[i].weight);
	for (i = 0; i < n; i++)    /*初始化連通圖*/
	{
		s[i][0] = 1;  /*第0列表示一個連通分量中頂點數*/
		s[i][1] = i;   /*第1列後的列中均表示頂點的編號*/
	}
	j = 0;     /*表示圖G陣列的序號*/
	i = 0;    /*表示樹中邊的序號*/
	while (i < n - 1)   /*找n-1條邊形成最小生成樹*/
	{
		k = 0;     /*k表示s陣列的行號*/
		while (k < n)  /*判斷兩個頂點為同一連通分量否*/
		{
			for (c = 1; c <= s[k][0]; c++)   /*找所在的行號*/
			{
				if (GE[j].fromvex == s[k][c])
					m1 = k;     /*起點行號*/
				if (GE[j].endvex == s[k][c])
					m2 = k;    /*終點行號*/
			}
			k++;
		}
		if (m1 != m2)    /*不是同一連通分量將圖中一條邊合併到樹中*/
		{
			TREE[i] = GE[j];
			/*把圖中的邊放到樹中*/
			i = i + 1;
			for (c = 1; c <= s[m2][0]; c++)
				/*修改連通分量*/
			{
				s[m1][0] = s[m1][0] + 1;
				/*頂點個數加1*/
				s[m1][s[m1][0]] = s[m2][c];
				/*終點編號合併*/
			}
			s[m2][0] = 0;
			/*合併後頂點數為0*/
		}
		j++;
	}
	for (i = 0; i < n - 1; i++)
	{
		printf("生成樹的起點,終點權值");
		printf("%d\t->%d\t%d\n", TREE[i].fromvex, TREE[i].endvex, TREE[i].weight);
	}
}
int main()
{
	while (1)
	{
		int choice;
		system("cls");
		printf("頂點請用從零開始的連續整數表示,權值請小於100");
		printf("\n\n\n");
		printf("          *****>主選單<*****\n\n\n");
		printf("           2----------克魯斯卡爾演算法\n");
		printf("           0----------退出程式\n");
		printf("\n\n enter your choice :");
		scanf("%d", &choice);
		if (choice < 0 || choice>3)
			return(0);
		switch (choice)
		{
		case 2:
			kruskl();
			system("pause");
			break;
		case 0:
			exit(0);
		}
	}
}