感觉这是自己写的最糟糕的代码,原来如此简单的算法,自己来实现,竟如此凌乱,也是醉了。最好不要参考我的写法,在网上看过其他人的,看不进去,觉得很乱。结果自己写完也很乱。所以,还是觉得找到契合自己感觉的代码,才能真正读下去吧。
思路:图用邻接矩阵存储,设置的大小是最多有9个点。selected数组用来存储已经选择的点,默认先选上1结点。然后每次遍历所有的已经选择的结点与其他还未选择的结点的权值,找出最小值,再将未选择的结点加入selected。另外设置一个isVisited记录某结点是否已经被选择。一直如此循环直到已经选择了sum个结点。sum的值的确定:isVisited数组全部默认无法访问,在读入结点的时候,每读入一个结点,就将对应数组中的位置设为true即可以访问。最后遍历一遍isVisited就可以得到有多少个可以访问的结点即sum的值。
一直没有养成写注释的习惯 一 一+ 现在实现了,已经不想再多看它一眼。╮(╯3╰)╭很多细节地方都是调bug临时修补的结果。
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
using namespace std;
#define MAXNUM 9
int graph[MAXNUM][MAXNUM];
bool isVisited[MAXNUM];
int selected[MAXNUM];
int SumWeight=0;
int sum;
void display()
{
cout<<"sumWeight: "<<SumWeight<<endl;
int i,j;
for (i=0; i<sum; i++)
{
cout<<selected[i]<<":";
for (j=1; j<MAXNUM; j++)
if (-1==graph[selected[i]][j])
cout<<j<<" ";
cout<<endl;
}
}
void createGraph(int V1,int V2,int weight)
{
graph[V1][V2]=weight;
graph[V2][V1]=weight;
isVisited[V1]=true;
isVisited[V2]=true;
}
void inputGraph()//将图的结点读入
{
char ch;
int V1,V2,weight;
do
{
cin>>ch;
if (ch!='#')
V1=ch-'0';
else break;
cin>>V2;
cin>>weight;
createGraph(V1,V2,weight);
}
while (1);
}
void Prim()
{
int i,j,V1=0,V2=0,temp,k=1,m;
for (i=0; i<MAXNUM; i++)
if (isVisited[i]) sum++;
i=0;
while (isVisited[V1]==false) V1++;
if (V1>=MAXNUM) return;
selected[i++]=V1;
isVisited[V1]=false;
while (k<sum)
{
temp=999;
for(j=0;j<i;j++)
{
for (m=1;m<MAXNUM;m++)
{
if ((graph[selected[j]][m]>0)&&(isVisited[m])&&(graph[selected[j]][m]<temp))
{
temp=graph[selected[j]][m];
V1=selected[j];
V2=m;
}
}
}
isVisited[V2]=false;
SumWeight+=graph[V1][V2];
graph[V1][V2]=-1;
graph[V2][V1]=-1;
selected[i++]=V2;
k++;
}
}
int main()
{
cout<<"请输入各边的权值,以#结束:(格式:顶点1 顶点6 权值3),"<<endl;
memset(isVisited,0,sizeof(isVisited));
inputGraph();//将图的信息读入,创建图
Prim();
display();
return 0;
}