问题
在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集(即)且为无循环图,使得的 w(T) 最小,则此 T 为 G 的最小生成树。
解析
在带权连通图中V是包含所有顶点的集合, U已经在最小生成树中的节点,从图中任意某一顶点v开始,此时集合U={v},重复执行下述操作:在所有u∈U,w∈V-U的边(u,w)∈E中找到一条权值最小的边,将(u,w)这条边加入到已找到边的集合,并且将点w加入到集合U中,当U=V时,就找到了这颗最小生成树。
设计
int prim(int cur)
{
int index = cur;
int sum = 0;
int i = 0 , j = 0;
cout << index << " ";
memset(visit,false, sizeof(visit));
visit[cur] = true;
for(i = 0; i < N; i++)
dist[i] = G[cur][i];
for(i = 1; i < N; i++)
{
int minn= INF;
for(j = 0; j < N; j++)
{
if(!visit[j] && dist[j] < minn)
{
minn = dist[j];
index = j;
}
}
visit[index] = true;
cout << index << " ";
sum += minn;
for(j = 0; j < N; j++)
{
if(!visit[j] && dist[j]>G[index][j]) dist
{
dist[j] = G[index][j];
}
}
}
cout << endl;
return sum;
}
源码
#include<iostream>
#include<cstring>
#define INF 10000
using namespace std;
const int N = 6;
bool visit[N];
int dist[N] = { 0, };
int G[N][N] = { {INF,7,4,INF,INF,INF},
{7,INF,6,2,INF,4},
{4,6,INF,INF,9,8},
{INF,2,INF,INF,INF,7},
{INF,INF,9,INF,INF,1},
{INF,4,8,7,1,INF}
};
int prim(int cur)
{
int index = cur;
int sum = 0;
int i = 0 , j = 0;
cout << index << " ";
memset(visit,false, sizeof(visit));
visit[cur] = true;
for(i = 0; i < N; i++)
dist[i] = G[cur][i];
for(i = 1; i < N; i++)
{
int minn= INF;
for(j = 0; j < N; j++)
{
if(!visit[j] && dist[j] < minn)
{
minn = dist[j];
index = j;
}
}
visit[index] = true;
cout << index << " ";
sum += minn;
for(j = 0; j < N; j++)
{
if(!visit[j] && dist[j]>G[index][j]) dist
{
dist[j] = G[index][j];
}
}
}
cout << endl;
return sum;
}
int main()
{
cout << prim(0) << endl;
return 0;
}