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 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; 百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库最小生成树总结(2)在线全文阅读。
相关推荐: