最近有些忙,先把最小生成树的代码挂上,有时间将讲解补上。
在这里两个函数: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; }
时间: 2024-10-06 23:26:05