UVA

Kruskal+并查集。

点很少,按边权值排序,枚举枚举L和R,并查集检查连通性。一旦连通,那么更新答案。

判断连通可以O(1),之前O(n)判的,第一次写的过了,后来T。。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 101;
const int maxe = maxn*maxn>>1;
int n,m;

int u[maxe],v[maxe],w[maxe];

int pa[maxn];

inline bool cmp(int a,int b) { return w[a]<w[b]; }
int r[maxe];

inline void idxSort()
{
    for(int i = 0; i < m; i++) r[i] = i;
    sort(r,r+m,cmp);
}

int Find(int x) { return x==pa[x]?x:pa[x]=Find(pa[x]); }
int cnt,ans;

inline void Union(int a,int b)
{
    int s1 = Find(a),s2 = Find(b);
    if(s1 != s2){
        pa[s1] = s2,cnt--;
    }
}


inline void initUFS() { for(int i = 1; i <= n; i++) pa[i] = i; cnt = n-1; }

const int INF = 0x3f3f3f3f;


int main()
{
    //freopen("in.txt","r",stdin);
    while(scanf("%d%d",&n,&m),n){
        for(int i = 0; i < m; i++)
            scanf("%d%d%d",u+i,v+i,w+i);

        idxSort();
        ans = INF;
        for(int i = 0; i < m; i++){
            initUFS();
            for(int j = i; j < m; j++){
                int R = r[j];
                Union(u[R],v[R]);
                if(!cnt) {
                    ans = min(ans,w[R]-w[r[i]]); break;
                }
            }
        }
        printf("%d
",ans==INF?-1:ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jerryRey/p/4757713.html