最小生成树-prime算法

本文探讨了最小生成树算法在构建交通网络中的应用,通过实例说明如何利用该算法最小化最长道路的长度,从而实现所有村镇间的高效连接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

prime算法的基本思想
1.清空生成树,任取一个顶点加入生成树
2.在那些一个端点在生成树里,另一个端点不在生成树里的边中,选取一条权最小的边,将它和另一个端点加进生成树

3.重复步骤2,直到所有的顶点都进入了生成树为止,此时的生成树就是最小生成树

1090. Highways

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has no public highways. So the traffic is difficult in Flatopia. The Flatopian government is aware of this problem. They're planning to build some highways so that it will be possible to drive between any pair of towns without leaving the highway system.

Flatopian towns are numbered from 1 to N. Each highway connects exactly two towns. All highways follow straight lines. All highways can be used in both directions. Highways can freely cross each other, but a driver can only switch between highways at a town that is located at the end of both highways.

The Flatopian government wants to minimize the length of the longest highway to be built. However, they want to guarantee that every town is highway-reachable from every other town.

Input

The first line is an integer N (3 <= N <= 500), which is the number of villages. Then come N lines, the i-th of which contains N integers, and the j-th of these N integers is the distance (the distance should be an integer within [1, 65536]) between village i and village j.

Output

You should output a line contains an integer, which is the length of the longest road to be built such that all the villages are connected, and this value is minimum.
This problem contains multiple test cases!
The first line of a multiple input is an integer T, then a blank line followed by T input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.
The output format consists of T output blocks. There is a blank line between output blocks.

Sample Input

1

3
0 990 692
990 0 179
692 179 0

Sample Output

692
#include<iostream>

using namespace std;

const int MAX=500;
const int INF=65536;
int arc[MAX][MAX];
bool visited[MAX];
int cost[MAX];
int longest;

void prime(int curr,int city){
	visited[curr]=true;
	int min=INF,index;
	longest=0;
	for(int i=0;i<city;i++){
		cost[i]=arc[curr][i];
	}
	for(int i=1;i<city;i++){
		min=INF;
		for(int j=0;j<city;j++){
			if(!visited[j]&&cost[j]<min){
				min=cost[j];
				index=j;
			}
		}
		visited[index]=true;
		if(min>longest)
			longest=min;
		for(int j=0;j<city;j++){
			if(!visited[j]&&arc[index][j]<cost[j]){
				cost[j]=arc[index][j];
			}
		}
	}
	
}


int main(){
	
	int t,city;
	cin>>t;
	while(t--){
		for(int i=0;i<MAX;i++)
			visited[i]=false;		
		cin>>city;
		for(int i=0;i<city;i++){
			for(int j=0;j<city;j++){
				cin>>arc[i][j];
			}
		}
		prime(0,city);
		cout<<longest<<endl;
		if(t)
			cout<<endl;	
	}
}


### 关于最小生成树的Prim算法 #### Prim算法的核心概念 Prim算法是一种用于解加权连通图中最小生成树的经典贪心算法。其基本思想是从任意一个顶点开始构建一颗树,逐步扩展这棵树直到覆盖所有的顶点[^1]。在此过程中,始终选择当前未加入树的顶点中最短的一条边来扩展树。 #### Prim算法的具体步骤 Prim算法通过维护两个集合完成计算:一个是已经加入最小生成树的顶点集合 \( S \),另一个是尚未加入的顶点集合 \( V-S \)[^2]。每次从未加入的顶点集中选取一条与已加入顶点集相邻且权重最小的边,并将对应的顶点纳入\( S \)中。这一过程持续进行,直到所有顶点都加入到\( S \)中为止。 #### Prim算法的时间复杂度分析 Prim算法的时间复杂度主要取决于如何存储和操作邻接关系以及优先队列的选择方式。当采用邻接矩阵表示时,时间复杂度为 \( O(V^2) \); 若使用二叉堆优化并配合邻接表,则可以降低至 \( O((V+E)\log V) \), 其中 \( V \) 是顶点数量,\( E \) 是边的数量[^3]。 #### C语言实现示例 以下是基于邻接矩阵的一个简单版本Prim算法实现: ```c #include <stdio.h> #define INF 9999999 #define MAX_VERTICES 100 int minKey(int key[], int mstSet[], int V){ int min = INF, min_index; for (int v = 0; v < V; v++) { if (!mstSet[v] && key[v] < min){ min = key[v]; min_index = v; } } return min_index; } void primMST(int graph[MAX_VERTICES][MAX_VERTICES], int V){ int parent[V]; int key[V]; int mstSet[V]; for (int i = 0; i < V; i++){ key[i] = INF; mstSet[i] = 0; } key[0] = 0; parent[0] = -1; for (int count = 0; count < V-1; count++){ int u = minKey(key, mstSet, V); mstSet[u] = 1; for (int v = 0; v < V; v++) if (graph[u][v] && !mstSet[v] && graph[u][v] < key[v]){ parent[v] = u; key[v] = graph[u][v]; } } printf("Edge\tWeight\n"); for (int i = 1; i < V; i++) printf("%d-%d\t%d\n", parent[i], i, graph[parent[i]][i]); } ``` 该程序定义了一个函数`primMST`, 它接收一个二维数组形式的邻接矩阵作为输入参数,并打印出构成最小生成树的所有边及其权重[^4]。 #### 总结 Prim算法提供了一种有效的方法来解决无向带权图上的最小生成树问题。它利用贪婪策略不断挑选最优局部决策从而达到全局最优目标。尽管存在其他替代方案如Kruskal算法,但在稠密图场景下,Prim通常表现更好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值