llllmz

导航

KY148 还是畅通工程C++

求图的最小生成树。克鲁斯卡尔算法来解决。就是选择n-1条最小边且无回路。

回路判断用并查集就行。

即要加入的边(两个节点)具有相同的父节点说明如果这两个节点本来就存在路径,再加入一条边就会产生回路,舍去。

#include<iostream>
#include<algorithm>
using namespace std;

struct node{
    int n1;
    int n2;
    int weight;
};
typedef struct node edge;

bool cmp(edge l, edge r){//true no exchange
    return l.weight <= r.weight;
}

void init_edge(edge e[]){
    for(int i=0;i<5000;i++){
        e[i].weight=9999;
        e[i].n1=-1;
        e[i].n2=-1;
    }
}

int getfather(int set[],int i){
    if(set[i]==i) return i;
    return getfather(set,set[i]);
}

void merge_set(int set[],edge e,int* sum){
    if(getfather(set,e.n1)!= getfather(set,e.n2)) {
        *sum+=e.weight;
        if(getfather(set,e.n1)<getfather(set,e.n2)){
            set[getfather(set,e.n2)]=getfather(set,e.n1);
        }else{
            set[getfather(set,e.n1)]=getfather(set,e.n2);
        }
    }
}

void init_set(int set[]){
    for(int i =0;i<101;i++){
        set[i]=i;
    }
}

int main(){
    int n=0;
    while(cin >> n){
        if(n==0) break;
        edge e[5000];
        int set[101]={0};
        init_set(set);
        init_edge(e);
        for(int i=0;i<n*(n-1)/2;i++){
            cin >> e[i].n1 >> e[i].n2 >> e[i].weight;
        }
        sort(e,&e[n*(n-1)/2],cmp);
        int sum=0;
        for(int i=0;i<n*(n-1)/2;i++){
            merge_set(set,e[i],&sum);
        }
        cout << sum <<'\n';
    }
    return 0;
}

 

结果如下:

posted on 2024-02-18 16:29  神奇的萝卜丝  阅读(27)  评论(0)    收藏  举报