UVA 1395 Slim Span (最小生成树+枚举)

题意:给出一个n(n<=100)结点的图,求苗条度(最大边减最小边的值)尽量小的生成树。

分析:枚举区间求最小生成树,不断更新ans

代码:

#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
#define mod 1000000007
#define mem(a) memset(a,0,sizeof(a))

using namespace std;

const int maxn = 5000 + 5 , inf = 0x3f3f3f3f ;

struct edge{
    int v,e,w;
    bool operator < (const edge&temp)const{
        return w<temp.w;
    }
};
edge edges[maxn];
int fa[maxn];
int n,m,ans,cnt;
void Init(){
    for(int i = 1 ; i < maxn ; i ++)
        fa[i] = i;
}
int Find(int u){return fa[u]==u?u:fa[u]=Find(fa[u]);}
void Kruskal(int L){
    cnt=0;
    Init();int Max = -inf,Min=inf;
    for(int j= L ; j <= m ;j ++){
        int v = edges[j].v;
        int e = edges[j].e;
        int w = edges[j].w;
        int x = Find(v);
        int y = Find(e);
        if(x!=y){
            cnt++;
            fa[x] = y;
            Max = max(Max,w);
            Min = min(Min,w);
            if(cnt==n-1){
                ans = min(ans,Max-Min);
                return;
            }
        }
    }
}
int main(){
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    while(scanf("%d%d",&n,&m)!=EOF&&(n||m)){
        ans = inf;
        for(int i = 1 ; i <= m ; i++)
            scanf("%d%d%d",&edges[i].v,&edges[i].e,&edges[i].w);
        sort(edges+1,edges+m+1);
        for(int i = 1 ; i <= m ; i ++){
            Kruskal(i);
        }
        printf("%d\n",ans!=inf?ans:-1);
    }
}

猜你喜欢

转载自blog.csdn.net/insist_77/article/details/80411377