UVA 1395 - Slim Span(MST)

UVA 1395 - Slim Span

题目链接

题意:给定一些结点和边,要求出最苗条度最小的生成树,苗条度定义为:生成树中最大权的边减去最小权的边的值

思路:类似建最小生成树的算法,多一步枚举起始边即可

代码:

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

const int N = 105;
const int INF = 0x3f3f3f3f;
int n, m, parent[N];

struct Edge {
	int u, v, val;
	Edge() {}
	Edge(int u, int v, int val) {
		this->u = u;
		this->v = v;
		this->val= val;
	}
	void read() {
		scanf("%d%d%d", &u, &v, &val);
	}
} e[N * N];

int find(int x) {
	return x == parent[x] ? x : parent[x] = find(parent[x]);
}

bool cmp(Edge a, Edge b) {
	return a.val < b.val;
}

int main() {
	while (~scanf("%d%d", &n, &m) && n || m) {
		for (int i = 0; i < m; i++)
			e[i].read();
		sort(e, e + m, cmp);
		int ans = INF;
		for (int i = 0; i < m; i++) {
			int cnt = 1;
			for (int j = 1; j <= n; j++) parent[j] = j;
			int flag = 1;
			for (int j = i; j < m; j++) {
				int u = find(e[j].u);
				int v = find(e[j].v);
				if (u != v) {
					parent[u] = v;
					cnt++;
				}
				if (cnt == n) {
					ans = min(ans, e[j].val - e[i].val);
					flag = 0;
					break;
				}
			}
			if (flag) break;
		}
		if (ans == INF) ans = -1;
		printf("%d\n", ans);
	}
	return 0;
}
时间: 2024-11-25 09:48:48

UVA 1395 - Slim Span(MST)的相关文章

UVa 1395 Slim Span (最小生成树)

题意:给定n个结点的图,求最大边的权值减去最小边的权值最小的生成树. 析:这个和最小生成树差不多,从小到大枚举左端点,对于每一个左端点,再枚举右端点,不断更新最小值.挺简单的一个题. #include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int maxn = 100 + 5; const int INF = 0x3f3f3f3f; int p[maxn]

UVa 1395 - Slim Span(最小生成树变形)

链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4141 题意: 给出一个n(n≤100)结点的图,求苗条度(最大边减最小边的值)尽量小的生成树. 分析: 首先把边按权值从小到大排序.对于一个连续的边集区间[L,R],如果这些边使得n个点全部连通,则一定存在一个苗条度不超过W[R]-W[L]的生成树(其中W[i]表示排序后第i条边的

11.2.2 例题 11-2 UVA 1395 Slim Span (最大值-最小值尽可能小的生成树)

题目大意: 给你n个点(n<=100),然后,让你找到一棵生成树,使得 最大值-最小值的边权尽可能的小的生成树. 解题思路: 还是按照最小生成树的思路,一开始对所有的边按照权值大小,从小到大排序.然后,对于一个区间[L,R],我们每次枚举的时候,如果这个[L,R]使得所有的n个点都联通了,那么定义他们的苗条度为: 最大值-最小值.这个苗条度肯定是<=cost[r]-cost[l].那么,我们就依次枚举这个l,每次都以[l,m]区间内的边建立最小生成树, 如果不能满足n个点的联通,那么就返回-1

1395 - Slim Span (最小生成树)

UVA上的题就是让人眼前一亮,不同于那些赤裸裸的生成树水题,该题稍加了变化,不是求最小生成树,而是求最苗条生成树 . 因为生成树有很多,而且每一棵生成树的最大边与最小边只差也是不确定的 .所以只能枚举所有的生成树 . 套用最小生成树模板 ,我们可以枚举生成树的起点位置,然后向后推终点位置,当n个点全部连通时,那么这棵生成树的边集就是[L,R] .因为边事先都排好序了, 那么该树的苗条值就是e[R] - e[L] . 这样从小到大枚举所有的L ,不断更新答案,就可以了 . 忍不住再说一下并查集,这

uva 1395 - Slim Span poj 3522 Slim Span(最小生成树算法)

最近学习了一下 最小生成树 算法. 所谓最小生成树算法,就是给出一个连通图g[ maxn ][ maxn  ], 找出这个连通图的边权和最小的生成图(树). 可以实现这个目的的算法,我叫它最小生成树算法.kruskal算法就是我学到的一种实现这种功能的算法. 对于kruskal算法的描述以及简单的证明在刘汝佳第二版上已经说得够明白 本题就是求 最小生成树 里面的 最大边权和最小边权 相差最小的最小生成树. #include<cstdio> #include<cstring> #in

UVA1395 Slim Span(kruskal)

题目:Slim Span UVA 1395 题意:给出一副无向有权图,求生成树中最小的苗条度(最大权值减最小权值),如果不能生成树,就输出-1: 思路:将所有的边按权值有小到大排序,然后枚举每一条边,以这条边开始利用Kruskal算法生成树,生成过程中求出权值的最大值,这个最大值减去当前枚举的边的权值就是苗条度,再动态维护一下最小苗条度就可以了. #include <iostream> #include <algorithm> #include <queue> #inc

POJ-3522 Slim Span(最小生成树)

Slim Span Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 8633   Accepted: 4608 Description Given an undirected weighted graph G, you should find one of spanning trees specified as follows. The graph G is an ordered pair (V, E), where V 

UVALive-3887 Slim Span (kruskal)

题目大意:定义无向图生成树的最大边与最小边的差为苗条度,找出苗条度最小的生成树的苗条度. 题目分析:先将所有边按权值从小到大排序,在连续区间[L,R]中的边如果能构成一棵生成树,那么这棵树一定有最小的苗条度.枚举所有这样的区间. 代码如下: # include<iostream> # include<cstdio> # include<set> # include<queue> # include<cstring> # include<al

UVA 1395 Slim Span (最小生成树,MST,kruscal)

题意:给一个图,找一棵生成树,其满足:最大权-最小权=最小.简单图,不一定连通,权值可能全相同. 思路:点数量不大.根据kruscal每次挑选的是最小权值的边,那么苗条度一定也是最小.但是生成树有多棵,苗条度自然也有多个,穷举下所有生成树,就知道了结果了.根据“只要起始边不同,生成树必定不同”来穷举起始边. 又发现一可能的坑!!我以为LONG_MAX就是int的正最大值,也就是2147483647=2^31-1,在我的机器上也许如此,在OJ上不一定了,用LONG_MAX转int会不同,得注意.