题意
求生成树的最长边与最短边的差值的最小值
题解
最小生成树保证每一条边最小,就只要枚举最小边开始,跑最小生成树,最后一个值便是最大值
在枚举最小边同时维护差值最小,不断更新最小值。
C++代码
/** /*@author Victor /*language C++ */ #include <bits/stdc++.h> #include<iostream> #include<algorithm> #include<cstdlib> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<bitset> #include<queue> #include<deque> #include<stack> #include<cmath> #include<list> #include<map> #include<set> //#define DEBUG #define RI register int using namespace std; typedef long long ll; //typedef __int128 lll; const int N=100000+10; const int MOD=1e9+7; const double PI = acos(-1.0); const double EXP = 1E-8; const int INF = 0x3f3f3f3f; #define pii pair<int,int> #define pll pair<ll,ll> #define pil pair<int , ll> #define pli pair<ll,int> #define pdl pair<double,ll> #define pld pair<ll,double> #define pdd pair<double,double> #define iput(n) scanf("%d",&n); #define dput(n) scanf("%lf",&n); #define llput(n) scanf("%lld",&n); #define cput(n) scanf("%s",n); #define puti(n) printf("%d\n",n); #define putll(n) printf("%lld\n",n); #define putd(n) printf("%lfd\n",n); #define _cls(n) memset(n,0,sizeof(n)); //求二进制中1的个数 //__builtin_popcount(n); //求2^k //#define (ll)Pow(2,k) (1LL<<k) struct edge { int u,v,cost; }eg[100001]; int n,m;//,father[100001]; bool cmp(edge e1,edge e2) { return e1.cost<e2.cost; } int par[N]; //父亲 int Rank[N]; //树的高度 //初始化n个元素 void init(int n) { for(int i=0; i<=n; ++i) { par[i] = i; Rank[i] = 0; } } //查询树的根非递归实现 int find(int x) { while(par[x]!=x) x=par[x]; return x; } //合并x和y所属集合 void unite(int x,int y) { int fx=find(x); int fy=find(y); if(fx==fy) return; if(Rank[fx]>Rank[fy]) par[fx]=fy; else { par[fy]=fx; if(Rank[fx]==Rank[fy]) Rank[x]++; } } //关于路径压缩 int find2(int x) { int fx=find(x); int t; while(x!=fx) { t=par[x]; par[x]=fx; x=t; } return fx; } // 最小生成树 Kruskal 算法 int minn; int Kruskal() { minn = 1e9; edge e; int i,res; sort(eg,eg+m,cmp); // 构建最小生成树 for(int j = 0;j < m; j ++){ init(n);res=0; for( i=j;i<m;++i ) { e=eg[i]; if( find(e.u)!=find(e.v) ) { unite(e.u,e.v); if(++res == n - 1) minn = min(minn,e.cost - eg[j].cost); } } } return res; } int main(){ while(scanf("%d%d",&n,&m)&&n+m){ for(int i = 0; i < m;++i){ scanf("%d%d%d",&eg[i].u,&eg[i].v,&eg[i].cost); } int ans = Kruskal(); bool flag = 1; if(minn != 1000000000) printf("%d\n",minn); else printf("-1\n"); } }