2609 最苗条的生成树
定义一颗树的苗条度为这棵树的最大边权与最小边权的差值。
现在有一个n个点m条边的无向联通图,求苗条度最小的生成树的苗条度是多少。
如图所示的数据中:最优的选取方案选取的生成树的三条边分别为(1-4,4-2,1-3),
所以答案为100-80=20。
输入
第1行:两个正整数n,m,n表示图中点的个数,m表示图中边的个数。(2<=n<=100,0<=m<=(n*(n − 1)/2)) 第2行-第m+1行:每行3个正整数,u,v,w,表示u和v之间有一条权值为w的边。(1<=u,v<=n,1<=w<=10000)输出
输出一个整数表示苗条度最小的生成树的苗条度。输入样例
4 6 1 2 10 1 3 100 1 4 90 2 3 20 2 4 80 3 4 40输出样例
20
思路:
本想水一发,没想到A了,做法的是枚举最小边然后到比该边大的边里找最小生成树,
事实这个做法是没有问题的。
因为:
因为根据Kruskal算法的原理,最小生成树的最短边确定后,最长边也相应确定,
他们的差值就确定(参见《算法导论》)。所以可以枚举最短边求出生成树。
具体来说,一个图的最小生成树不一定是唯一的,但是组成这些最小生成树的
各个边的权值一定都是一一对应相同的。不会出现这种一个树上有两个边权值a+b等于
另外一颗树上两个边c+d,然后这两个树都是最小生成树的情况。
上述内容大佬博客拼接而成。。。
代码实现:
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<cstdio>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
using namespace std;
const int N=2e5+100;
const int M=4e5+100;
const int mod=1e9+7;
struct Node {
int l,r,val;
} err[M];
bool cmp(Node aa,Node bb) {
return aa.val<bb.val;
}
int fat[N];
int find(int x) {
return x==fat[x]?x:fat[x]=find(fat[x]);
}
int main() {
#ifdef MYHOME
freopen("input.txt","r",stdin);
#endif
int maxs,n,m,mini,ans;
while(cin>>n>>m) {
mini=ans=INF;
maxs=0;
for(int i=1; i<=n; i++)fat[i]=i;
for(int i=1; i<=m; i++) {
cin>>err[i].l>>err[i].r>>err[i].val;
}
sort(err+1,err+1+m,cmp);
for(int i=1; i<=)
}
return 0;
}
THE END;