最小生成树总结(2)

2020-04-18 07:54

edg++; } } } }

int main() {

int test,i,j;

scanf(\ while(test--) {

scanf(\ for(i=0;i

for(j=0;j

scanf(\ } }

makeline();

int m=Kruskal(); printf(\ }

return 0; }

总之来说,Kruskal算法就是贪心算法的运用,贪心规则:每一次选取一条边,此条边的一个端点在当前树中,另一个不在当前树中,而且当前选的这条边是符合要求的具有最小权值的边,如果符合要求,则添加到当前集合中,如此往复,直到边数为N-1是停止。

Prim算法

Prim算法是在连通,加权图中寻找最小生成树的另一种贪心算法,除特别申明,图的权值为正值;它不同于Kruskal算法的地方不仅是算法本身,而有一个地方要注意的地方时prim算法求出来的最小生成树是连通的树,而Kruskal算法的部分解不一定是连通的。

Prim算法从一个定点开始,然后实施贪心规则:添加一条最小权重的边,它的一个顶点在当前树中,而另一个顶点不知当前树中。 实现prim算法有3种(就我所知),第一种:比较简单,就是直接贪心,复杂度比较高O(n^2) 第二种:采用优先队列,复杂度改进了很多,O(m*lgN),如果你用的是STL的queue,速度会很慢,有的时候可能会TLE,所以一般都建议自己首先优先队列,优先队列用二叉小根堆来实现。第三种:采用斐波那契(Fibonacci)堆实现,这种方法更是优化了很多,复杂度

降到了O(m+N*lgN);不过这种方法比较难懂,很复杂。

第一种:

朴素实现,复杂度O(N^2)

首先定义一个map[MAX][MAX]数组,map[i][j]表示定义i和顶点j之间路的权值,如果没有路,这权值为无穷大;dis[MAX]用来保存当前符合要求的边的权值;vis[MAX]用来标记顶点是否被访问过,如果没有则是false,如果已经访问则是true;

朴素实现代码模板如下: int prim() {

int res=0,i,j,t;

memset(vis,0,sizeof(vis));

for(i=0;i

dis[i]=map[0][i]; //初始化dis[MAX]数组,初始化为于0链接的路线的权值

vis[0]=true; ////////0被访问了,所以修改为true

for(i=1;i

int min=INF; t=0;

for(j=0;j

if(!vis[j]&&min>dis[j]) {

min=dis[j]; t=j; } } res+=min; vis[t]=true;

for(j=0;j

if(!vis[j]&&map[t][j]

dis[j]=map[t][j]; }

} }

return res; }

用这个方法解决HOJ 题目:

Jungle Roads

Jungle Roads

题目描述如下:

Time limit: 1sec. Memory limit: 32M

Submitted: 270 Accepted: 183

Source: ACM ICPC Mid-Central USA 2002

The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid money was spent on extra roads between villages some years ago. But the jungle overtakes roads relentlessly, so the large road network is too expensive to maintain. The Council of Elders must choose to stop maintaining some roads. The map above on the left shows all the roads in use now and the cost in aacms per month to maintain them. Of course there needs to be some way to get between all the villages on

maintained roads, even if the route is not as short as before. The Chief Elder would like to tell the Council of Elders what would be the smallest amount they could spend in aacms per month to maintain roads that would connect all the villages. The villages are labeled A through I in the maps above. The map on the right shows the roads that could be

maintained most cheaply, for 216 aacms per month. Your task is to write a program that will solve such problems.

The input consists of one to 100 data sets, followed by a final line containing only 0. Each data set starts with a line containing only a

number n, which is the number of villages, 1 < n < 27, and the villages are labeled with the first n letters of the alphabet, capitalized. Each data set is completed with n-1 lines that start with village labels in alphabetical order. There is no line for the last village. Each line for a village starts with the village label followed by a number, k, of roads from this village to villages with labels later in the alphabet. If k is greater than 0, the line continues with data for each of the k roads. The data for each road is the village label for the other end of the road followed by the monthly maintenance cost in aacms for the road. Maintenance costs will be

positive integers less than 100. All data fields in the row are separated by single blanks. The road network will always allow travel between all the villages. The network will never have more than 75 roads. No village will have more than 15 roads going to other villages (before or after in the alphabet). In the sample input below, the first data set goes with the map above.

The output is one integer per line for each data set: the minimum cost in aacms per month to maintain a road system that connect all the villages. Caution: A brute force solution that examines every possible set of roads will not finish within the one second time limit. Sample Input 9

A 2 B 12 I 25 B 3 C 10 H 40 I 8 C 2 D 18 G 55 D 1 E 44

E 2 F 60 G 38 F 0

G 1 H 35 H 1 I 35 3

A 2 B 10 C 40 B 1 C 20

0

Sample Output 216 30

实现代码如下: #include #include using namespace std; #define MAX 30 #include

const int INF=99999999;

int map[MAX][MAX],dis[MAX]; bool vis[MAX]; int N;

int prim() {

int res=0,i,j,t;

memset(vis,0,sizeof(vis));

for(i=0;i

dis[i]=map[0][i]; //初始化dis[MAX]数组,初始化为于0链接的路线的权值

vis[0]=true; ////////0被访问了,所以修改为true

for(i=1;i

int min=INF; t=0;

for(j=0;j

if(!vis[j]&&min>dis[j]) {

min=dis[j]; t=j; } } res+=min;


最小生成树总结(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2018届浙江省杭州市高考英语模拟试卷三(解析版)

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: