关闭

HDU1102(最小生成树Kruskal算法)

标签: kruskalhdu
410人阅读 评论(0) 收藏 举报
分类:

Constructing Roads

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 19847    Accepted Submission(s): 7594


Problem Description
There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A and B are connected, if and only if there is a road between A and B, or there exists a village C such that there is a road between A and C, and C and B are connected.

We know that there are already some roads between some villages and your job is the build some roads such that all the villages are connect and the length of all the roads built is minimum.
 

Input
The first line is an integer N (3 <= N <= 100), 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, 1000]) between village i and village j.

Then there is an integer Q (0 <= Q <= N * (N + 1) / 2). Then come Q lines, each line contains two integers a and b (1 <= a < b <= N), which means the road between village a and village b has been built.
 

Output
You should output a line contains an integer, which is the length of all the roads to be built such that all the villages are connected, and this value is minimum.
 

Sample Input
3 0 990 692 990 0 179 692 179 0 1 1 2
 

Sample Output

179

首先将已有的顶点放入集合中,然后再kruskal

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

struct node {
	int u, v, w;
}edge[10010];

#define mem(a) memset(a, 0, sizeof(a))
int par[110]; 
int cmp(node a, node b) {
	return a.w < b.w;
}

int find(int a) {
	if (a != par[a])	return find(par[a]);
	else	return a;
}

int kruskal(int n, int num) {
	int ans = 0;
	sort(edge, edge+num, cmp);
	
	for (int i = 0; i<num; i++) {
		int x = edge[i].u, y = edge[i].v;
		x = find(x), y = find(y);
		if (x != y) {
			ans += edge[i].w;
			par[y] = x;
		}
	}
	return ans;
}

int main() {
	int n;
	while (cin >> n) {
		mem(edge);
		mem(par);
		int num = 0;
		for (int i = 1; i<=n; i++) {
			for (int j = 1; j<=n; j++) {
				int k;
				cin >> k;
				if (i >= j)	continue;
				edge[num].u = i;
				edge[num].v = j;
				edge[num++].w = k;
			}	
		}
		for (int i = 1; i<=n; i++)	par[i] = i;
		int q;
		cin >> q;
		while (q --) {
			int x, y;
			cin >> x >> y;
			x = find(x);
			y = find(y);
			par[x] = y;
		}
		cout << kruskal(n, num) << endl;
	}
	return 0;
}



0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

最小生成树之Kruskal算法

给定一个无向图,如果它任意两个顶点都联通并且是一棵树,那么我们就称之为生成树(Spanning Tree)。如果是带权值的无向图,那么权值之和最小的生成树,我们就称之为最小生成树(MST, Minimum Spanning Tree)。      ...
  • luomingjun12315
  • luomingjun12315
  • 2015-08-18 08:12
  • 26240

最小生成树-kruskal算法

Kruskal算法按照边的权重大小处理,每一次从待选边中选出最小的边,企图加入到生成树当中。但此时存在一个问题,若当前边加入生成树后存在环路,则该边废弃。一直重复这一过程,直到所有的点都已经加入生成树,或含有V-1条边,V为顶点个数。
  • turingwy
  • turingwy
  • 2016-02-19 15:36
  • 1475

最小生成树Kruskal算法朴素版 C语言实现

最小生成树Kruskal算法朴素版 C语言实现
  • sunshineacm
  • sunshineacm
  • 2017-12-11 22:15
  • 79

数据结构:最小生成树--Kruskal算法

Kruskal算法 求解最小生成树的另一种常见算法是Kruskal算法,它比Prim算法更直观。从直观上看,Kruskal算法的做法是:每次都从剩余边中选取权值最小的,当然,这条边不能使已有的边产生回路。 手动求解会发现Kruskal算法异常简单,下面是一个例子 算法说明 为了判...
  • zhangxiangDavaid
  • zhangxiangDavaid
  • 2014-08-07 11:45
  • 5028

贪婪算法-最小生成树-Kruskal算法

最小生成树是找出图中包括所有结点的联通子图,使得其所有的边的权重之和最小。 Kruskal 算法提供一种在 O(ElogV) 运行时间确定最小生成树的方案。其选择的贪心策略就是,每次都选择权重最小的但未形成环路的边加入到生成树中。其算法结构如下: 将所有的边按照权重非递减排序;选择最小权重的边...
  • u010726042
  • u010726042
  • 2016-04-10 21:47
  • 669

Kruskal算法(贪心+并查集=最小生成树)

http://www.51nod.com/ Kruskal算法的高效实现需要一种称作并查集的结构。我们在这里不介绍并查集,只介绍Kruskal算法的基本思想和证明,实现留在以后讨论。 Kruskal算法的过程: (1) 将全部边按照权值由小到大排序。 (2) 按顺序(边权由小到大的顺序)...
  • liangzhaoyang1
  • liangzhaoyang1
  • 2016-04-16 17:34
  • 7213

Prim算法和Kruskal算法构造最小生成树

最小生成树 首先,生成树是建立在无向图中的,对于有向图,则没有生成树的概念,所以接下来讨论的图均默认为无向图。对于一个有n个点的图,最少需要n-1条边使得这n个点联通,由这n-1条边组成的子图则称为原图的生成树。一般来说,一个图的生成树并不是唯一的(除非原图本身就是一棵树)。 现在考虑带权图G,...
  • qq_18230813
  • qq_18230813
  • 2015-07-31 23:19
  • 1050

最小生成树之Kruskal和Prim算法——C++实现

很久以前就学过最小生成树之Kruskal和Prim算法,这两个算法很容易理解,但实现起来并不那么容易。最近学习了并查集算法,得知并查集可以用于实现上述两个算法后,我自己动手实现了最小生成树算法。 宏观上讲,Kruskal算法就是一个合并的过程,而Prim算法是一个吞并的过程,另外在Prim算法中还用...
  • lrgdongnan
  • lrgdongnan
  • 2016-06-18 17:16
  • 3904

最小生成树,克鲁斯卡尔算法(Python实现)

克鲁斯卡尔算法的基本思想:设有一个有n个顶点的连通网N={V,E},最初先构造一个只有n个顶点,没有边的非连通图T={V, E},图中每个顶点自成一个连通分量。当在E中选到一条具有最小权值的边时,若该边的两个顶点落在不同的连通分量上,则将此边加入到T中;否则将此边舍去,重新选择一条权值最小的边。如此...
  • HeiSeDiWei
  • HeiSeDiWei
  • 2015-12-17 13:56
  • 2566

最小生成树——Kruskal算法(C语言版)

1,问题描述 设G=(V,E)是无向连通带权图,如果G的一个子图G’是一棵包含G的所有顶点的树,则称G’为G的生成树。生成树的各边权的总和称为该生成树的耗费,求在G的所有生成树中耗费最小的最小生成树。 2,算法思想 (1)将代价树中权值非0的所有的边进行小顶堆排序,依次存入到road[]数组中...
  • cslgliuzezhong
  • cslgliuzezhong
  • 2014-12-04 09:49
  • 1455
    个人资料
    • 访问:71209次
    • 积分:2289
    • 等级:
    • 排名:第18954名
    • 原创:162篇
    • 转载:6篇
    • 译文:0篇
    • 评论:6条
    博客专栏