POJ 3522 Slim Span(Kruskal)

 

有 n 个点,m 条边,求 n 个点连接起来时最大边与最小边差的最小值 

按照边的权值进行排序,这样只需要遍历每 n-1 条边,寻找出答案即可

const int N=2e5+5;
 
    int n,m,t;
    int i,j,k;
    int fa[N];
struct node
{
    int u,v,w;
}G[N];
bool cmp(node a,node b)
{
    if(a.w!=b.w) return a.w<b.w;
    if(a.u!=b.u) return a.u<b.u;
    return a.v<b.v;
}

int Find(int x)
{
    if(fa[x]==x) return x;
    return fa[x]=Find(fa[x]);
}
int Kruskal()
{
    int ans=inf;
    sort(G+1,G+1+m,cmp);
    for(int i=1;m-i+1>=n-1;i++){//枚举起始边,及边权最小边
        int res=-1,num=0;
        for(int j=1;j<=n;j++) fa[j]=j;
        for(int j=i;j<=m;j++){//边权最大边
            int x=Find(G[j].u);
            int y=Find(G[j].v);
            if(x==y) continue;
            num++;
            fa[x]=y;
            if(num==n-1){
                res=G[j].w-G[i].w;
                break;
            }
        }
        if(res!=-1) ans=min(ans,res);
    }
    return ans;
}
int main()
{
    //IOS;
    while(sdd(n,m)==2){
        if(n==0 && m==0) break;
        for(i=1;i<=m;i++) sddd(G[i].u,G[i].v,G[i].w);
        int ans=Kruskal();
        if(ans==inf) puts("-1");
        else pd(ans);
    }
    return 0;
    //PAUSE;
}

猜你喜欢

转载自blog.csdn.net/C_Dreamy/article/details/107820792