Kruskal實例練習(二)

網絡

Andrew是某個公司的系統管理員,他計劃爲他的公司搭建一個新的網絡。在新的網絡中,有N個集線器,在集線器之間可以通過網線連接。由於公司職員需要通過集線器訪問整個網絡,因此每個集線器必須能通過網線連接其它集線器(可以有中轉集線器)。由於有不同的長度可選,且網線越短越便宜,因此Andrew設計的方案必須確保最長的單根網線的長度在所有方案中最小。試幫助Andrew設計一個網絡,滿足上述條件~


輸入描述:
輸入文件中包含多個測試數據。每個測試數據的第1行爲兩個整數:N和M,N表示網絡中集線器的數目,2<=N<=1000,集線器的編號從1~N;M表示集線器之間的連接數
目,1<=M<=15000。接下來M行描述了M對連接的信息,每對連接的格式爲:所連接的兩個集線器的編號,連接這兩個集線器所需的網線的長度,且長度爲不超過1000000的正整數。兩個集線器之間最多有一對連接:每個集線器都不能與自己連接。測試數據保證網絡是連通的。測試數據一直到文件尾。

輸出描述:
對輸入文件中的每個測試數據,首先輸出連接方案中最長的單根網線的長度(這個值取到最小);然後輸出設計方案:先輸出一個整數P,代表所使用的網線數目;然後輸出P對頂點,表示每根網線所連接的集線器編號,整數之間用空格或換行符隔開。

樣例輸入:
5 8
1 2 5
1 4 2
1 5 1
2 3 6
2 4 3
3 4 5
3 5 4
4 5 6

樣例輸出:
4
4
1 5
1 4
2 4
3 5

解:
本題和實例一種的思路差不多,不過要注意輸出的要求——先輸出最長的單根網線的長度,再輸出選出的邊,所以要再附加一個數組ans來存儲選出的邊的信息~
代碼+註釋:

#include<stdio.h>
#include<stdlib.h>

#define MAXN 1001			//頂點個數最大值
#define MAXM 150001			//邊的個數最大值

typedef struct edge
{
	int u, v, w;			//起點、終點、權值
}edge;
edge edges[MAXM];			//鄰接矩陣

int parent[MAXN];			//頂點i所在集合的根結點
int N, M;					//頂點數和邊數
int ans[MAXM], ai;			//存儲選出的邊
int i, j;					//循環變量
int num;					//記錄選出的邊的個數
int maxedge;				//最長邊

void UFset()				//將parent初始化
{
	for(i = 1; i <= N; i++) parent[i] = -1;
}

int Find(int x)				//找到頂點x所在集合的根結點
{
	int s, tmp;
	for(s = x; parent[s] >= 0; s = parent[s]) ;
	while(s != x)
	{
		tmp = parent[x];
		parent[x] = s;
		x = tmp;
	}
	return s;
}

void Union(int R1, int R2)	//合並不在同一集合的兩點
{
	int r1 = Find(R1), r2 = Find(R2);
	int tmp = parent[r1] + parent[r2];
	if(parent[r1] > parent[r2])
	{
		parent[r1] = r2;
		parent[r2] = tmp;
	}
	else 
	{
		parent[r2] = r1;
		parent[r1] = tmp;
	}
}

void Kruskal()
{
	UFset();
	for(i = 0; i < M; i++)
	{
		if(Find(edges[i].u) != Find(edges[i].v))
		{
			ans[ai] = i; ai++;		//記錄選中的邊
			if(edges[i].w > maxedge) maxedge = edges[i].w;
			num++;					//記錄選中的邊的個數
			Union(edges[i].u, edges[i].v);
		}
		if(num >= N-1) break;
	}
}

int cmp(const void *a, const void *b)
{
	return (*(const edge *)a).w-(*(const edge *)b).w;
}

int main()
{
	while(scanf("%d%d", &N, &M) != EOF)
	{
		for(i = 0; i < M; i++)
			scanf("%d%d%d", &edges[i].u, &edges[i].v, &edges[i].w);
		qsort(edges, M, sizeof(edges[0]), cmp);
		maxedge = 0; num = 0; ai = 0;
		Kruskal();
		printf("%d\n", maxedge);
		printf("%d\n", num);
		for(i = 0; i < ai; i++)
			printf("%d %d\n", edges[ans[i]].u, edges[ans[i]].v);
	}
	return 0;
}

運行結果:


發佈了77 篇原創文章 · 獲贊 35 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章