本文主要是介绍POJ-3522 Slim Span 最小生成树最小边权差,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目大意:n个点m条边 用n-1条边连接n个点并边权差最小
思路:枚举最小边 + Kruskal
#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 105;
const int inf = 1<<30;
int n,m;
int sum;
int p[maxn];
struct node
{int u,v,w;
}edge[maxn*maxn];
bool cmp( node a,node b )
{return a.w < b.w;
}
int find(int x)
{ return x!=p[x]?p[x]=find(p[x]):x;
}
bool merge( int i )
{int x = find(edge[i].u);int y = find(edge[i].v);if( x != y ){p[x] = y;sum ++;if( sum == n-1 )return true;}return false;
}
int Kruskal()
{int ans = inf,dis;sort(edge,edge+m,cmp); //对边从小到大排序for( int s = 0; s <= m-n + 1; s ++ ){ //枚举最小边sum = 0;for( int i = 1; i <= n; i ++ )p[i] = i;for( int i = s; i < m; i ++ ){if( merge(i) ){ //合并并判断是否构成n-1条边dis = edge[i].w - edge[s].w;ans = ans < dis?ans:dis;break;}}}return ans == inf?-1:ans;
}
int main()
{// freopen("data.txt","r",stdin); int a,b,w;while( scanf("%d%d",&n,&m) == 2,(n||m) ){for( int i = 0; i < m; i ++ ){scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w);}printf("%d\n",Kruskal());}return 0;
}
这篇关于POJ-3522 Slim Span 最小生成树最小边权差的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!