POJ 1251 Jungle Roads (最小生成树 Kruskal克鲁斯卡尔算法)

本文介绍了一个使用快速排序和并查集实现的最小生成树算法。通过定义道路结构体,并运用快速排序对道路成本进行排序,确保了算法的高效运行。此外,通过并查集来避免形成环路,从而计算出连接所有村庄的最低成本路径。
摘要由CSDN通过智能技术生成
#include <stdio.h>

#define MAX_ROADS 76
#define MAX_VILLAGES 27

struct ROAD{
	int start;
	int end;
	int cost;
};

ROAD roadArray[MAX_ROADS];
int numOfRoads;
int roadNum;

int numOfVillages;

int parent[MAX_VILLAGES];

void roadCopy(ROAD *to, ROAD *from){
	ROAD temproad;
	temproad.start = from->start;
	temproad.end = from->end;
	temproad.cost = from->cost;
	from->start = to->start;
	from->end = to->end;
	from->cost = to->cost;
	to->start = temproad.start;
	to->end = temproad.end;
	to->cost = temproad.cost;
}
void quickSortroadsAccordingToCost(int start, int end){
	if (start >= end){
		return;
	}
	while (start < end){
		int left = start;
		int right = end;
		ROAD pivotroad;
		roadCopy(&pivotroad, &roadArray[start]);
		while (left < right){
			while (left < right && roadArray[right].cost >= pivotroad.cost){
				right--;
			}
			roadCopy(&roadArray[left], &roadArray[right]);
			while (left < right && roadArray[left].cost <= pivotroad.cost){
				left++;
			}
			roadCopy(&roadArray[right], &roadArray[left]);			
		}
		roadCopy(&roadArray[left], &pivotroad);
		int pivot = left;
		quickSortroadsAccordingToCost(start, pivot - 1);
		start = pivot + 1;
	}
}

int getParent(int villageNum){
	while (parent[villageNum]){
		villageNum = parent[villageNum];
	}
	return villageNum;
}
int main(){
	//freopen("input.txt", "r", stdin);

	while (1){
		scanf("%d", &numOfVillages);
		if (numOfVillages == 0){
			return 0;
		}

		numOfRoads = 0;
		int indexOfVillage;
		for (indexOfVillage = 1; indexOfVillage <= numOfVillages; indexOfVillage++){
			parent[indexOfVillage] = 0;
		}

		for (indexOfVillage = 1; indexOfVillage < numOfVillages; indexOfVillage++){
			char villageLetter;
			int numOfAdjaRoads;
			scanf(" %c %d", &villageLetter, &numOfAdjaRoads);
			int start = villageLetter - 'A' + 1;
			int indexOfRoad;
			for (indexOfRoad = 1; indexOfRoad <= numOfAdjaRoads; indexOfRoad++){
				int cost;
				scanf(" %c %d", &villageLetter, &cost);
				int end = villageLetter - 'A' + 1;
				numOfRoads++;
				roadNum = numOfRoads;
				roadArray[roadNum].start = start;
				roadArray[roadNum].end = end;
				roadArray[roadNum].cost = cost;
			}
		}

		quickSortroadsAccordingToCost(1, numOfRoads);

		int minTotalCost = 0;
		int indexOfRoad;
		for (indexOfRoad = 1; indexOfRoad <= numOfRoads; indexOfRoad++){
			int start = roadArray[indexOfRoad].start;
			int end = roadArray[indexOfRoad].end;
			int parentOfStart = getParent(start);
			int parentOfEnd = getParent(end);
			if ( parentOfStart != parentOfEnd ){
				parent[parentOfStart] = parentOfEnd;
				minTotalCost += roadArray[indexOfRoad].cost;
			}
		}

		printf("%d\n", minTotalCost);		
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值