最小生成树,经典题目
好好学习prime 与Kruskal,觉得Kruskal比较简单,就是并查集加排序,而prime像是树到点的Dijkstra,还有觉得不好学可以看看《啊哈!算法》
prime
#include<stdio.h>
#include<string.h>
#define INF 0x3f3f3f
int a[105][105];
int dis[105];
bool book[105];
int main(){
int n,i,j,cnt,sum,min;
while(~scanf("%d",&n)){
memset(book,false,sizeof(book));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&(a[i][j]));
for(i=1;i<=n;i++)
dis[i]=a[1][i];
book[1]=true;
cnt=1;
sum=0;
while(cnt!=n){
min=INF;
for(i=1;i<=n;i++){
if(!book[i] && min>dis[i]){
j=i;
min=dis[i];
}
}
book[j]=true;
cnt++;
sum+=dis[j];
for(i=1;i<=n;i++){
if(!book[i]&& dis[i]>a[j][i])
dis[i]=a[j][i];
}
}
printf("%d\n",sum);
}
return 0;
}
Kruskal
#include<stdio.h>
#include<algorithm>
using namespace std;
int f[102];
struct node{
int a,b,v;
}a[10000];
int find(int a){
return a==f[a]?a:(f[a]=find(f[a]));
}
void merge(int a,int b){
f[find(b)]=find(a);
}
int cmp(node a,node b){
return a.v <b.v ;
}
int main(){
int i,j,v,k,cnt,sum;
int n;
while(~scanf("%d",&n)){
for(i=1;i<=n;i++) f[i]=i;
k=0;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
scanf("%d",&v);
if(j>i){
a[k].a=i;
a[k].b=j;
a[k++].v=v;
}
}
}
sort(a,a+k,cmp);
// for(i=0;i<k;i++)
// printf("%d %d %d\n",a[i].a,a[i].b,a[i].v );
sum=0;
cnt=0;
for(i=0;i<k&&cnt!=n-1;i++){
if(find(a[i].a )!=find(a[i].b )) {
//printf("%d %d %d\n",a[i].a ,a[i].b ,a[i].v );
merge(a[i].a ,a[i].b );
sum+=a[i].v;
cnt++;
}
}
printf("%d\n",sum);
}
return 0;
}