对于最小生成树,有两种算法可以解决。一种是Prim算法,该算法的时间复杂度为O(n²),与图中边数无关,该算法适合于稠密图,而另外一种是Kruskal,该算法的时间主要取决于边数,它较适合于稀疏图。
#define nMAX 2003
#define INF 0x3ffffff
int map[nMAX][nMAX];
/** 节点数 */
int n;
/** 是否已加入集合, visit[i] = 1 表示节点i已加入连通集合 */
int visit[nMAX];
/** 到已连通集合的最短距离 */
int dis[nMAX];
/** 节点v 到已连通集合的距离为dis */
struct Node{
int v; //路线的终点
int dis; //路线的长度
};
priority_queue<Node> q;
bool operator < ( Node node1, Node node2 ){
return node1.dis > node2.dis;
}
int prim()
{
int i, size = 1, sum = 0;
visit[0] = 1;
Node node;
for( i = 1; i < n; i ++ ){
dis[i] = map[0][i];
node.v = i;
node.dis = map[0][i];
q.push( node );
}
/** size 表示已加入连通集合的节点数 */
while( size < n ){
node = q.top();
q.pop();
if( visit[node.v] == 1 )
continue;
visit[node.v] = 1;
size ++;
sum += node.dis;
/** 更新每个节点到连通集合的最短距离 */
for( i = 1; i < n; i ++ ){
if( !visit[i] && dis[i] > map[node.v][i] ){
dis[i] = map[node.v][i];
Node tmp;
tmp.v = i;
tmp.dis = map[node.v][i];
q.push( tmp );
}
}
}
return sum;
}