适合稀疏图,
C语言注释版,复习用
//kruskal
#include<stdio.h>
#include<stdlib.h>
#define DIRECTED 0
typedef sturct
{
int v;
int w;
}edge;
typedef struct
{
edge edges[MAXN][MAXN];
int degree[MAXN];
int nvertices;
int nedges;
}graph;
int main(void)
{
graph g;
int i,j;
int x,y,weight;
memset(0,g->degree,sizeof(g->degree));
scanf("%d %d",&g->nvertices,&g->nedges);//点数,边数
for(i=1;i<=g->nvertices;i++)
{
scanf("%d %d %d",&x,&y,&weight);
degree[x]++;
edges[x][degree[x]].v=y;
edges[x][degree[x]].w=weight;
if(!DIRECTED)
{
degree[y]++;
edges[y][degree[y]].v=x;
edges[y][degree[y]].w=weight;
}
}
return 0;
}
//边的两端点分别保存在数组u和数组v中,权值保存在数组w中
int Kruskal(){
for(int i = 1; i <= m; ++i) r[i] = i; //初始化边序号
for(int i = 1; i <= n; ++i) p[i] = i;//初始化并查集
sort(r+1, r+m+1, cmp);//边排序
int k = 0, ans = 0;
for(int i = 1 ; i <= m; ++i) {
int e = r[i];//从小到大遍历边
int x = find(u[e]), y = find(v[e]);//并查集检验连通分量
if(x!=y)//当两者不在同一个连通分量内,将边插入
{
ans += w[e];
++k;//k值应该为在最小生成树内的边数
p[x] = y;//改边,将末端值顺便修改,增加并查集效率
}
if ( k == n-1 )//提前结束
break;
}
int root = find(1);//检验是否有奇葩事件,防止错误
for(int i =1 ;i <=n; ++i) if(find(i)!=root) return -1;
return ans;
}
C++模板
struct KRUSKAL
{
const int MAXN = 109;
const int MAXE = 5009;
struct EDGE
{
int u, v, length, choose;
} edge[ MAXE ];
int path[ MAXN ];
int N, edgecnt, sum;
void Addedge(int u, int v, int len)
{
++edgecnt;
edge[ edgecnt ].u = u;
edge[ edgecnt ].v = v;
edge[ edgecnt ].length = len;
edge[ edgecnt ].choose = false;
return ;
}
void Set()
{
for (int i = 1; i <= N; i++)
path[i] = i;
return ;
}
int Find_Path(int x)
{
if (x != path[x]) path[x] = Find_Path( path[x] );
return path[x];
}
int Work()
{
int cnt = 0, x, y;
Qsort(1, edgecnt); // i < j -> edge[i].length < edge[j].length
Set();
for (int i = 1; i <= E && cnt < N - 1; i++)
{
x = Find_Path( edge[i].u );
y = Find_Path( edge[i].v );
if (x == y) continue;
path[x] = path[y];
edge[i].choose = true, ++cnt;
sum += edge[i].length;
}
return sum;
}
} Kruskal;
邪恶的超简洁代码,背板
#include <iostream>
using namespace std;
const int MAXV = 1024, MAXE = 100001;
int n, m, f[MAXV], ans, cnt;
struct edge{
int f, t, w;
}es[MAXE];
bool cmp(const edge &a, const edge &b){
return a.w < b.w;
}
void Fill(int &a){
static int cnt = 0;
a = ++cnt;
}
int get(int x){
return x == f[x] ? x : f[x] = get(f[x]);
}
void Kruskal(const edge &e){
if(get(e.f) != get(e.t)){
f[get(e.f)] = get(e.t);
ans += e.w;
cnt++;
}
}
void Read(edge &e){
cin>>e.f>>e.t>>e.w;
}
int main()
{
cin>>n>>m;
for_each(es+1, es+m+1, Read);
make_heap(es+1, es+m+1, cmp);
sort_heap(es+1, es+m+1, cmp);
for_each(f+1, f+n+1, Fill);
for_each(es+1, es+m+1, Kruskal);
cout<<(cnt < n-1 ? -1: ans)<<endl;
return 0;
}