标准最小生成树
本文提供两种做法:
- Prim
- Kruscal
Prim解法:
#include<iostream>
#include<math.h>
using namespace std;
struct tag_point{
double x,y;
}point[105];
double map[105][105];
int N;
bool judge[105];
double dis(int i,int j){
return sqrt((point[i].x-point[j].x)*(point[i].x-point[j].x)+(point[i].y-point[j].y)*(point[i].y-point[j].y));
}
double Prim(){
int i,j,tnum,k;
double sum=0,tmin;
//初始化判断数组
for(i=1;i<=N;i++)
judge[i]=false;
judge[1]=true;
//Prim
for(k=1;k<N;k++){
tmin=0x3f3f3f3f;
tnum=0;
for(i=1;i<=N;i++){
for(j=2;j<=N;j++){
if(!judge[j]&&judge[i])
if(map[i][j]<tmin){
tmin=map[i][j];
tnum=j;
}//end if
}//end j
}// end i
judge[tnum]=true;
sum+=tmin;
}//end k
return sum;
}
int main(){
int i,j;
//freopen("1.txt","r",stdin);
while(cin>>N){
for(i=1;i<=N;i++){
cin>>point[i].x>>point[i].y;
}// end cin
for(i=1;i<=N;i++){
for(j=1;j<=N;j++){
if(i==j)
map[i][j]=0x3f3f3f3f;
else{
map[i][j]=dis(i,j);
}//end if
}//end j
}// end i
printf("%.2lf\n",Prim());
}
return 0;
}
Kruscal解法
#include<iostream>
#include<algorithm>
using namespace std;
typedef struct tag_point{
int x,y,dis;
}P;
P point[5000];
int father[105];
int find(int x){//寻找父节点,顺便压缩下路径
if(x==father[x])
return x;
int t=find(father[x]);
father[x]=t;
return t;
}
int cmp(const P &a,const P &b){
return a.dis<b.dis;
}
int main(){
int n,i,sum,t,x,y,c;
//freopen("1.txt","r",stdin);
while(scanf("%d",&n)!=EOF&&n){
t=(n*(n-1))/2;
for(i=0;i<t;i++){
scanf("%d%d%d",&point[i].x,&point[i].y,&point[i].dis);
}
sort(point,point+t,cmp);//从小到大排列
for(i=1;i<=n;i++){//初始化
father[i]=i;
}
sum=0;//记住最小生成树的值
c=0;
for(i=0;i<t && c!=n;i++){
x=find(point[i].x);
y=find(point[i].y);/
if(x!=y){
sum+=point[i].dis;
c++;
father[x]=y;
}
}
printf("%d\n",sum);
}
return 0;
}