Kruskal算法(一)之 C语言详解
Prim 在稠密图中比 Kruskal 优,在稀疏图中比 Kruskal 劣。
Kruskal:时间复杂度由排序算法决定,若采用快排则时间复杂度为O(N*logN)
例题
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int pre[120010];//祖先
struct node{
int x,y,w;
}t[120010];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
while(a!=pre[a])
a=pre[a];
return a;
}
int merge(int x,int y)//合并
{
int xx=find(x);
int yy=find(y);
if(xx!=yy)
{
pre[xx]=yy;
return 1;
}else{
return 0;
}
}
int main()
{
int n,m;
while(cin>>n,n)
{
cin>>m;
for(int i=0;i<=n;i++)
pre[i]=i;
for(int i=0;i<m;i++)
cin>>t[i].x>>t[i].y>>t[i].w;
sort(t,t+m,cmp);
int sum=0,num=0;
for(int i=0;i<m;i++)
{
if(merge(t[i].x,t[i].y))
{
sum++;
num+=t[i].w;
if(sum==n-1) break;
}
}
cout<<num<<endl;
}
return 0;
}
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int n;
int pre[110];//祖先
//边
struct node{
int x,y;
double w;
}t[120010];
//球的坐标,半径
struct node2{
double x,y,z,r;
}ball[200];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int a)
{
int i=a,j;
while(a!=pre[a])
a=pre[a];
//压缩路径,提高效率
//并查集中也可以用到
while(i!=a){
j=pre[i];
pre[i]=a;
i=j;
}
return a;
}
int judge(int x,int y)//检查
{
int xx=find(x);
int yy=find(y);
if(xx!=yy)
{
pre[xx]=yy;
return 1;
}else{
return 0;
}
}
int init()
{
for(int i=0;i<=n;i++)
pre[i]=i;
}
int main()
{
while(cin>>n,n)
{
int num=0;;
init();
for(int i=0;i<n;i++)
{
cin>>ball[i].x>>ball[i].y>>ball[i].z>>ball[i].r;
for(int j=0;j<i;j++)
{
double s1=(ball[i].x-ball[j].x)*(ball[i].x-ball[j].x);
double s2=(ball[i].y-ball[j].y)*(ball[i].y-ball[j].y);
double s3=(ball[i].z-ball[j].z)*(ball[i].z-ball[j].z);
double R=sqrt(s1+s2+s3)-(ball[i].r+ball[j].r);
t[num].x=i;
t[num].y=j;
t[num++].w=R;
}
}
sort(t,t+num,cmp);
int numm=0;
double sum=0;
for(int i=0;i<num;i++)
{
if(judge(t[i].x,t[i].y))
{
numm++;
if(t[i].w>0)
sum+=t[i].w;
}
if(numm==n-1) break;
}
printf("%.3f\n",sum);
}
return 0;
}
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=30;
const int M=150;
char c;
int n,num;
int pre[N];
struct node{
int x,y,w;
}p[M];
bool cmp(node a,node b)
{
return a.w<b.w;
}
int find(int x)
{
return x==pre[x]?x:pre[x]=find(pre[x]);
}
void init()
{
for(int i=0;i<=N;i++)
pre[i]=i;
}
int kruskal()
{
int test=1;
int sum=0;
for(int i=1;i<num;i++)
{
if(test==n) break;
int xx=find(p[i].x);
int yy=find(p[i].y);
if(xx!=yy)
{
pre[xx]=yy;
sum+=p[i].w;
++test;
}
}
return sum;
}
int main()
{
while(cin>>n,n)
{
num=1;
init();
for(int i=1;i<n;i++)
{
int a;
scanf("%c%d",&c,&a);
cin>>c>>a;
int use=c-'A';
for(int j=1;j<=a;j++)
{
cin>>c>>p[num].w;//不可直接对 p[num].w 使用 scanf
p[num].x=use;
p[num].y=c-'A';
num++;
}
}
sort(p+1,p+num,cmp);
printf("%d\n",kruskal());
}
return 0;
}
#include <iostream>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdio>
#include <stack>
#include <algorithm>
#include <queue>
using namespace std;
const int MAX=110;
int pre[MAX];
int n;
int test=0;
int num=0;
struct node{
int x,y;
int w;
}road[40010];
bool cmp(node a,node b){
return a.w<b.w;
}
void init(int v){
for(int i=0;i<=v;i++)
pre[i]=i;
}
int find(int x){
return x==pre[x]?x:pre[x]=find(pre[x]);
}
bool join(int a,int b){
int fa=find(a);
int fb=find(b);
if(fa!=fb){
pre[fa]=fb;
return 1;
}
return 0;
}
int kruskal(){
int sum=0;
for(int i=1;i<num;i++){
if(test==n-1)
break;
if(join(road[i].x,road[i].y)){
test++;
sum+=road[i].w;
}
}
return sum;
}
int main(){
while(cin>>n){
init(n);
num=1;
test = 0;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>road[num].w;
road[num].x=i;
road[num].y=j;
num++;
}
}
int q;
cin>>q;
for(int i=0;i<q;i++){
int a,b;
cin>>a>>b;
if(join(a,b))
test++;
}
sort(road+1,road+num+1,cmp);
cout<< kruskal() <<endl;
}
return 0;
}