Kruskal算法求最小生成树(POJ2485)

题目链接:http://poj.org/problem?id=2485

#include <iostream>
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>

using namespace std;

#define inf 100000000
#define N 505
#define M N*N

struct note {
    int u,v;
    int c;
    note() {}
    note(int u,int v,int c):u(u),v(v),c(c) {}
} p[M];

int e,n,m;
int father[N];      ///表示x的父亲的编号


void addnote(int u,int v,int c) {
    p[e++]=note(u,v,c);
}

int cmp(const void *a,const void *b) {
    note *aa=(note *)a;
    note *bb=(note *)b;
    return aa->c-bb->c;
}

///初始化每个节点的祖先,即为独立的点
void set_clear() {
    for(int i=0; i<=n; i++)
        father[i]=i;
}

///找到x的祖先。
int find(int x) {
    if(x!=father[x])
        father[x]=find(father[x]);
    return father[x];
}

int kruskal(int n) {
    set_clear();
    int m=0;        ///只要找n-1条边,就把图构成了
    int ans=0;
    for(int i=0; i<e; i++) {
        int x=find(p[i].u);
        int y=find(p[i].v);
        if(x==y) continue;

        m++;
        ans=p[i].c;
        father[y]=x;        ///father[y]的祖先改为x;合并两个不相交的集合
        if(m==n-1) break;
    }
    if(m<n-1) return -1;
    else return ans;
}

int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        e=0;        ///边的个数
        for(int i=1; i<=n; i++) {
            for(int j=1; j<=n; j++) {
                int c;
                scanf("%d",&c);
                addnote(i,j,c);
            }
        }
        qsort(p,e,sizeof(p[0]),cmp);
        printf("%d
",kruskal(n));
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/TreeDream/p/5388722.html