求图的最小生成树。克鲁斯卡尔算法来解决。就是选择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;
}
结果如下:
标签:KY148,set,weight,int,回路,C++,edge,畅通,节点 From: https://www.cnblogs.com/llllmz/p/18016744