HDU 1233最小生成树 Kruscal 算法

来源:互联网 发布:新加坡进出口数据 编辑:程序博客网 时间:2024/06/06 00:37

Kruscal 是一种贪心策略。
按边长从小到大排序,

枚举每条边时,考察这条边的两个定点:

1.这两个顶点属于同一个集合则舍弃这条边。

2.这两个顶点不属于同一个集合则采取这条边,同时合并这两个顶点。

判断两个点属于哪个集合需要用到并查集

下面AC代码


#include<cstdio>#include<algorithm>using namespace std;typedef long long ll;const int maxn = 105;int n;struct edge{    int from,to;    ll cost;}E[maxn*maxn];int father[maxn];int cmp(edge n1,edge n2){    return n1.cost < n2.cost;}void init(){ // 并查集初始化 初始化为:各个顶点孤立    for(int i = 1;i <= n;++i) father[i] = i;}int find(int x){  // 并查集    if(x == father[x]) return x;    else return father[x] = find(father[x]);}int main(){    while(scanf("%d",&n) != EOF){        if(n == 0) break;        init();        for(int i = 0;i < n*(n-1)/2;++i){            scanf("%d%d%lld",&E[i].from,&E[i].to,&E[i].cost);        }        sort(E,E+n*(n-1)/2,cmp);        ll res = 0;        for(int i = 0;i < n*(n-1)/2;++i){            if(find(E[i].from) == find(E[i].to)) continue;  // 判断两个顶点是否属于同一个集合            res += E[i].cost;            father[find(E[i].from)] = find(E[i].to);        }        printf("%lld\n",res);    }    return 0;}

0 0
原创粉丝点击