`
kenby
  • 浏览: 724744 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

poj 1251 kruskal算法求最小生成树

阅读更多

 

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

#define DEBUG

#ifdef DEBUG
#define debug(...) printf( __VA_ARGS__) 
#else
#define debug(...)
#endif

#define N 27
#define MAX_INT 20000000

using namespace std;

struct eg{
	char x;
	char y;
	int w;
};

struct eg edge[75];

char parent[N];	/* MF Set, 树根的parent为负数,其绝对值表示这棵树的高度 */

int n, m;

/* 找i的根节点 */
int find(int i)
{
	for(; parent[i] >= 0; i = parent[i]) ;
	return i;
}

void merge(int x,int y, int px, int py)
{

	if (px == py) return;
	debug("%d的树根为%d,树高=%d,%d的树根为%d, 树高=%d\n", x, px, -parent[px], y, py, -parent[py]);
	if (parent[px] < parent[py]) {	/* x所在的树比y所在的树要高 */
		parent[py] = px;
		debug("合并后树根为%d, 高度=%d\n", px, -parent[px]);
	}
	else if (parent[px] > parent[py]) { /* x所在的树比y所在的树要矮 */
		parent[px] = py;
		debug("合并后树根为%d, 高度=%d\n", py, -parent[py]);
	}
	else {
		parent[py] = px;
		parent[px]--;	/* 树的高度加1 */
		debug("合并后树根为%d, 高度=%d\n", px, -parent[px]);
	}
}

static int 
compare(const void *p1, const void *p2)
{
	return ((struct eg *)p1)->w - ((struct eg *)p2)->w;
}

int kruskal() 
{
	int 	i, total_cost;
	int		px, py;

	total_cost = 0;
	qsort(edge, m, sizeof(eg), compare);	/* 按边的长度从小到大排序 */
	memset(parent, -1, sizeof(parent));

	for (i = 0; i < m; i++) {
		debug("%c-%c : %d\n", edge[i].x+'A', edge[i].y + 'A', edge[i].w);
	}

	for (i = 0; i < m; i++) {
		px = find(edge[i].x);
		py = find(edge[i].y);
		if (px != py) {		/* 这条边的两个顶点不在同一个集合中 */
			merge(edge[i].x, edge[i].y, px, py);
			debug("边%c-%c加入集合, 长度为%d\n", edge[i].x+'A', edge[i].y+'A', edge[i].w);
			total_cost += edge[i].w;
		}
	}
	return total_cost;
}


int main()
{
	int 	i, j, w;
	char	ch;
	char	adj;

	while (cin >> n && n) {
		m = 0;
		for (i = 1; i < n; i++) {
			cin >> ch >> j;
			while (j--) {
				cin >> adj >> w;
				edge[m].x = ch-'A';
				edge[m].y = adj-'A';
				edge[m].w = w;
				m++;
			}
		}
		debug("总共有%d条边\n", m);
		printf("%d\n", kruskal());
	}	
	return 0;
}
分享到:
评论

相关推荐

    poj1251 最小生成树

    标题“poj1251 最小生成树”是一个编程竞赛题目,来源于著名的在线编程平台POJ(Programming Online Judge)。这个题目主要涉及图论中的一个经典算法问题——最小生成树(Minimum Spanning Tree, MST)。在图论中,...

    POJ 1679 练习克鲁斯卡尔kruskal 算法

    【标题】"POJ 1679 练习克鲁斯卡尔Kruskal算法" 在图论领域,克鲁斯卡尔(Kruskal)算法是一种用于解决最小生成树问题的有效方法。这个问题涉及到在一个加权无向图中找到一棵包括所有顶点的树,其边的权重之和尽...

    最小生成树题解1

    对于这些题目,理解最小生成树的基本算法如 Prim 和 Kruskal 是关键,同时要注意根据具体问题的特性调整算法的应用。在实际编程时,还需要注意数据结构的选择,例如使用优先队列(二叉堆)优化 Prim 算法,或者使用...

    最小生成树(MST)问题——北京大学暑期课《ACM/ICPC竞赛训练》

    构造最小生成树主要有两种经典算法:Prim算法和Kruskal算法。 **Prim算法** Prim算法是一种贪心算法,其基本思想是从某个顶点出发,逐步选择与当前已构建的生成树相连接的边中权重最小的边加入生成树中,直到生成...

    POJ算法题目分类

    * 最小生成树算法:最小生成树算法是指计算图的最小生成树的算法,如 prim、kruskal。 * 拓扑排序:拓扑排序是指计算图的拓扑排序的算法,如 poj1094。 * 二分图的最大匹配:二分图的最大匹配是指计算二分图的最大...

    POJ中级图算法所有题目【解题报告+AC代码】

    2. **最小生成树**:Prim算法和Kruskal算法是两种常见的构建最小生成树的方法。Prim算法从一个顶点开始逐步添加边,而Kruskal算法则是按边的权重从小到大加入,确保不形成环路。 3. **拓扑排序**:对于有向无环图...

    POJ第1861题源码POJ第1861题源码POJ第1861题源码POJ第1861题源码

    对于POJ第1861题,参赛者可能需要读取输入数据,构建一个加权图,然后应用Prim或Kruskal算法找出最小生成树,最后输出树中边的权重总和或者某种特定格式的树结构。解题过程可能涉及到错误处理、边界条件检查以及效率...

    poj 2485 Highways 测试数据

    在【压缩包子文件的文件名称列表】中,"poj 2485 Highways (最小生成树)"可能是题目提供的样例输入和输出文件,用于检验自己编写的程序是否正确。这些样例通常包含了各种边界情况和特殊案例,以确保算法的鲁棒性。 ...

    POJ 1861 Network

    常见的求解最小生成树的算法有Prim算法和Kruskal算法。在这个问题中,由于需要先进行快速排序,Kruskal算法更为合适,因为它依赖于边的排序。Kruskal算法的基本步骤是: 1. 将所有边按权重从小到大排序。 2. 初始化...

    poj解题报告2395

    Kruskal算法是一种贪心算法,其核心思想是每次选取权重最小的边加入到生成树中,直到生成树包含所有顶点为止。具体步骤如下: 1. **初始化**:将图中的所有顶点看作独立的集合。 2. **排序**:按照边的权重从小到大...

    北大POJ初级-基本算法

    6. **图论算法**:包括图的遍历(深度优先搜索和广度优先搜索)、最短路径问题(Dijkstra算法、Floyd-Warshall算法)、最小生成树问题(Prim和Kruskal算法)。 7. **字符串处理**:如KMP算法、Rabin-Karp算法、...

    北大POJ初级-图算法

    5. **Prim算法和Kruskal算法**:这两种都是解决最小生成树问题的算法,适用于无权图或带权重的图。Prim算法从一个节点开始,每次添加一条最小的边,直到连接所有节点;而Kruskal算法则是按边的权重从小到大排序,...

    Poj中的一些题目源代码

    这里可能是在Kruskal算法的基础上改进,寻找具有特定性质的最小生成树,例如尽可能窄或直径小。 5. **P2497.cpp** - 由于没有具体题目描述,这可能涉及到一个通用的算法问题,可能需要查阅POJ上的原题来获取更多...

    ACMer需要掌握的算法讲解 (2).docx

    * 最小生成树算法:prim、kruskal、POJ1789、POJ2485、POJ1258、POJ3026 * 拓扑排序:POJ1094 * 串算法:POJ1035、POJ3080、POJ1936 * 哈希表和二分查找等高效查找法:POJ3349、POJ3274、POJ2151、POJ1840、POJ2002...

    ACMer需要掌握的算法讲解.docx

    6. 最小生成树算法(prim, kruskal)(poj1789, poj2485, poj1258, poj3026) 7. 拓扑排序(poj1094) 8. 串(poj1035, poj3080, poj1936) 9. 哈希表和二分查找等高效查找法(poj3349, poj3274, POJ2151, poj1840, ...

    poj训练计划.doc

    - 最小生成树算法:如Prim算法和Kruskal算法,用于找出图中的最小生成树,如`poj1789, poj2485`。 - 拓扑排序:适用于有向无环图,用于确定任务的执行顺序,如`poj1094`。 - 二分图的最大匹配:如匈牙利算法,...

    poj2485.rar_poj2485

    总结来说,这个压缩包提供了一个使用最小生成树算法解决POJ2485题目的实例,它涉及了图论、贪心算法、C++编程和在线编程竞赛实践等多个IT领域的知识点。通过分析和学习这个解题代码,我们可以加深对最小生成树算法的...

    ACM-POJ 算法训练指南

    2. **最小生成树**:Prim算法和Kruskal算法,用于构建图的最小生成树(poj1789, poj2485, poj1258, poj3026)。 3. **网络流**:Max-flow算法,用于解决最大流问题(poj1094)。 4. **拓扑排序**:解决有向无环图的...

    poj pku图论、网络流入门题总结、汇总

    - **解题思路:** 可以先通过Prim或Kruskal算法找到最小生成树,然后通过改变权重值的方法来判断最小生成树是否唯一。 - **注意事项:** 判断最小生成树是否唯一的方法有多种,除了通过修改权重外,还可以考虑使用并...

    poj题目分类

    * 最小生成树算法:例如 Prim、Kruskal,例如 poj1789、poj2485、poj1258、poj3026。 * 拓扑排序:例如 poj1094。 * 二分图的最大匹配:例如 poj3041、poj3020。 * 最大流的增广路算法:例如 poj1459、poj3436。...

Global site tag (gtag.js) - Google Analytics