最小生成树

Prime:从点0开始不断拉相邻权重最小且不构成回路的点进来
Kruskal:在原图中不断找权重最小的边“记录在案”,保证不构成回路

Prime算法(稠密矩阵;邻接矩阵)

从点0开始不断拉相邻权重最小且不构成回路的点进来(形成一个超点)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

void prime(int G[N][N]){
Edge edges[N];
for(int i=0;i<N;i++){
edges[i].vex = 0;//表示"0"到各个节点
edges[i].cost = G[0][i];//距离
}
edges[0].cost = 0;//距离"0"表示不可达
printf("%d ",edges[0].vex);
for(int a=1;a<N;a++){
int k = select(edges);
printf("%d(last: %d) ",k,edges[k].vex);
edges[k].cost = 0;
for(int i=0;i<N;i++){
if(G[k][i]<edges[i].cost){
edges[i].vex = k;//表示到i这个点是从k走更近一点
edges[i].cost = G[k][i];
}
}
}
}
int select(Edge edges[]){
int val = INT_MAX;int idx = -1;
for(int i=0;i<N;i++){
if(edges[i].cost<val&&edges[i].cost>0){
val = edges[i].cost;
idx = i;
}
}
return idx;
}

Kruskal(稀疏矩阵;邻接表)

在原图中不断找权重最小的边“记录在案”,保证不构成回路(通过与标记过的点不属于同一连通分量gno实现)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

void kruskal(TGraph* G){
    heapsort(G);//稍微排个序
    int idx=1;int num=0;
for(int i=1;i<G->nv;i++){
while(1){
if(G->pv[G->pe[idx].va].gno!=G->pv[G->pe[idx].vb].gno){
int a=G->pv[G->pe[idx].va].gno,b=G->pv[G->pe[idx].vb].gno;
for(int j=1;j<idx;j++){
if(G->pv[G->pe[j].va].gno==a) G->pv[G->pe[j].va].gno=b;
if(G->pv[G->pe[j].vb].gno==a) G->pv[G->pe[j].vb].gno=b;
}
G->pv[G->pe[idx].va].gno=b;
printf("%d-%d ",G->pe[idx].va,G->pe[idx].vb);break;
}
else idx++;
}
idx++;
}
}