链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4141
题意:给出n个顶点,m条边,求一个生成树,使得最大边与最小边的差值最小。
思路:求一个生成树使最大边最小是瓶颈生成树。对于此题,我们枚举每一条边做最小边的情况,找对应的最小生成树的最大边,找出最大边与最小边差值最小的值即可。
#include<cstring> #include<string> #include<fstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cctype> #include<algorithm> #include<queue> #include<map> #include<set> #include<vector> #include<stack> #include<ctime> #include<cstdlib> #include<functional> #include<cmath> using namespace std; #define PI acos(-1.0) #define MAXN 50100 #define eps 1e-7 #define INF 0x7FFFFFFF #define LLINF 0x7FFFFFFFFFFFFFFF #define seed 131 #define MOD 1000000007 #define ll long long #define ull unsigned ll #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 struct node{ int u,v,w; }edge[MAXN]; int n,m,father[110],maxm; bool cmp(node x,node y){ return x.w<y.w; } int Find(int x){ int t = x; while(t!=father[t]) t = father[t]; int k = x; while(k!=t){ int temp = father[k]; father[k] = t; k = temp; } return t; } bool kruskal(int x){ int i,j; maxm = 0; for(i=0;i<=n;i++) father[i] = i; int sum = 0; for(i=x;i<m;i++){ int a = Find(edge[i].u); int b = Find(edge[i].v); if(a!=b){ father[a] = b; sum++; maxm = max(maxm,edge[i].w); if(sum>=n-1) return true; } } return false; } int main(){ int i,j; while(scanf("%d%d",&n,&m),n||m){ for(i=0;i<m;i++){ scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w); } sort(edge,edge+m,cmp); int ans = INF; for(i=0;i<m;i++){ if(m-i<n-1) break; if(kruskal(i)){ ans = min(ans,maxm-edge[i].w); } } if(ans==INF) puts("-1"); else printf("%d\n",ans); } return 0; }
时间: 2024-10-11 11:24:06