最小生成树

含义

  • 一个无向有权图,找权重和最小的连通子图(生成树)

常见所需元素

  • edge结构体
  • kruscal算法
  • 并查集
  • 排序(按边的权重)

模板(自创)

  • 和并查集有大量重复
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int father[100];
int depth[100];

struct edge{		//边结构体
    int from;
    int to;
    int len;
};

edge E[5000];		//开n(*n-1)/2个边

bool cmp(edge x,edge y){
    return x.len<y.len;
}

void init(int n){
    for(int i=0;i<=n;i++){
        father[i]=i;
        depth[i]=0;
    }
}

int find(int x){
    if(x!=father[x]){
        father[x]=find(father[x]);
    }
    return father[x];
}

void Union(int x,int y){
    x=find(x);
    y=find(y);
    if(x!=y){
        if(depth[x]>depth[y]){
            father[y]=x;
        }
        else if(depth[y]>depth[x]){
            father[x]=y;
        }
        else{
            father[x]=y;
            depth[y]++;
        }
    }
    return;
}

int Kruscal(int N,int edgeNumber){		//kruscal核心算法模板
    init(N);
    sort(E,E+edgeNumber,cmp);
    int sum=0;
    for(int i=0;i<edgeNumber;i++){
        edge current=E[i];
        if(find(current.from)!=find(current.to)){
            Union(current.from,current.to);
            sum+=current.len;
        }
    }
    return sum;
}

int main(){
    int N;
    while(scanf("%d",&N)!=EOF){
        if(N==0) break;
        int edgeNumber=(N-1)*N/2;
        for(int i=0;i<edgeNumber;i++){
            cin>>E[i].from>>E[i].to>>E[i].len;
        }
        cout<<Kruscal(N,edgeNumber)<<endl;
    }
    return 0;
}

例题

posted @ 2021-03-23 13:53  LazyXx  阅读(29)  评论(0)    收藏  举报