最近有些忙,先把最小生成树的代码挂上,有时间将讲解补上。
在这里两个函数:Prim和Kruskal函数,分别是这两个算法的主算法代码。使用的图存储方式是邻接矩阵。
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
#define MAX 100
#define INT_MAX 10000
#define min(x,y)(x<y?x:y)
typedef struct{
int matrix[MAX][MAX]; //邻接矩阵
int num;// 最大的顶点数
}Graph;
int InitNode;
Graph example; //实例图
// 初始化图
void initGraph(){
int i,j;
for(i=0;i<MAX;i++){
for(j=0;j<MAX;j++){
example.matrix[i][j]=INT_MAX;
}
}
example.num=0;
}
void createPoint(){
int i,j,val;
initGraph();
while(cin>>i>>j>>val){
if(i==0 && j==0) break;
example.matrix[i][j]=val;
example.matrix[j][i]=val;
example.num = max(example.num,i);
//这里偷了个懒,我这里假设顶点之间序号是连续的,没有点之间
//序号跨很大的情况,如果需要的话,大家可以写一个函数改一下
//这里。
example.num = max(example.num,j);
}
}
//输出最后的最短路径
void printResult(int *from,int *lowcost,int n){
cout<<"--------------------------"<<endl;
for(int i=1;i<=n;i++){
if(i!=InitNode) cout<<from[i]<<"->"<<i<<":"<<lowcost[i]<<endl;
}
}
void Prim(){
int *S = new int[example.num+1]; //已选择集合
int *lowcost = new int[example.num+1]; //最小权值
int *processed = new int[example.num+1]; //记录已选择
int *from = new int[example.num+1]; //记录从哪个结点到对应下标点的
//数组初始化
for(int i=0;i<=example.num;i++){
lowcost[i] = INT_MAX;
}
memset(from,0,sizeof(from));
memset(processed,0,sizeof(processed));
//将初始点放入集合中
int count = 1,NowProPoint = InitNode;
S[count]=NowProPoint; processed[NowProPoint]=1;count++;
while(count<=example.num){
int minval = INT_MAX, minInd = -1;
for(int i=1;i<=example.num;i++){
if(processed[i]!=1){
if(lowcost[i]>example.matrix[NowProPoint][i]){
lowcost[i] = example.matrix[NowProPoint][i];
from[i] = NowProPoint;
}
if(minval>lowcost[i]){
minval = lowcost[i];minInd = i;
}
}
}
S[count]=minInd; processed[minInd]=1;count++;
NowProPoint = minInd;
//输出lowcost的变化过程
cout<<"--------------------------"<<endl;
for(int i=1;i<=example.num;i++){
cout<<lowcost[i]<<" ";
}
cout<<endl;
}
printResult(from,lowcost,example.num);
}
void kruskal(){
//这个kruskal算法使用堆的时间复杂度是o(eloge),但是因为用了邻接矩阵作为存储方式
//所以是o(n3)。。
int shortPath,x,y;
int *processed = new int[example.num+1]; //联通分量
//数组初始化
for(int i=0;i<=example.num;i++){
processed[i]=i; //一开始每个节点为一个连通分量
}
int count = 1;
cout<<"--------------------------"<<endl;
while(count<example.num){
shortPath = INT_MAX;x=-1;y=-1;
for(int i=1;i<=example.num;i++){
for(int j=1;j<=example.num;j++){
if(shortPath>example.matrix[i][j] && (processed[i]!=processed[j])){
shortPath = example.matrix[i][j];
x= i ;y =j;
}
}
}
//将两个连通分量合并成一个
for(int i=1;i<=example.num;i++){
if(processed[i]==processed[x]) processed[i]=processed[y];
}
count++;
//输出最短路径
cout<<x<<"->"<<y<<":"<<shortPath<<endl;
}
}
int main(){
InitNode =1;
createPoint();
Prim();
kruskal();
return 0;
}