问题:
输入一个二维数组,标识无向图
比如上面的这个图,输入对应的二维数组:其中4标识维度
4
0 2 4 0
2 0 3 5
4 3 0 1
0 5 1 0
使用普利姆算法求出其中最小生成树
思路:
1,用visited数组存储每个点是否被确定了,确定了就变为1,不是就变为0
2,用lowcast数组来存储每次生成树对应的最短距离,每次都用找到的这个最小的点,看他到其他点的距离,拿这个距离和上一次的lowcast进行比较,找到比上一次的小的,并存入到lowcast中
代码:
#include<iostream>
using namespace std;
int n;
int prime(int **p,int v){//返回最短路径
int temp[n][n];//用来存储树
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
temp[i][j]=0;
}
}
int sum=0;
//定义一个visited数组,初始化为0
int visited[n];
for(int i=0;i<n;i++){
visited[i]=0;
}
//定义一个lowcast数组存储数到其他顶点的最短距离
int lowcast[n];
//先将lowcast和visited初始化
visited[v]=1;
for(int i=0;i<n;i++){
lowcast[i]=p[v][i];//存储的是从v到其他顶点的距离,0标识的无穷大
}
for(int i=1;i<n;i++){//在将其他剩余的n-1个visited进行循环,补充
int min;//每次找到lowcast中的最小的
int min_i;
for(int j=0;j<n;j++){//找到其中非0的最小的
if(visited[j]==0&&lowcast[j]!=0){//没有访问过的点并且找到此刻最小的那个点
min=lowcast[j];
min_i=j;
break;
}
}
for(int j=min_i;j<n;j++){
if(visited[j]==0&&lowcast[j]!=0){//没有访问过的点并且找到此刻最小的那个点
if(min>lowcast[j]){
min=lowcast[j];
min_i=j;
}
}
}
temp[v][min_i]=min;
temp[min_i][v]=min;
v=min_i;
//把此刻最小的那个点对应的visited变为1,标识确定了这个点
visited[min_i]=1;
//然后把这个点对应的边的值和lowcast进行比较,将更小的点存到lowcast,确定lowcast数组
for(int j=0;j<n;j++){
if(visited[j]==0&&p[min_i][j]!=0){
if(lowcast[j]==0){//标识无穷
lowcast[j]=p[min_i][j];
}else{
if(lowcast[j]>p[min_i][j]){
lowcast[j]=p[min_i][j];
}
}
}
}
}
for(int i=0;i<n;i++){
sum+=lowcast[i];
}
cout<<endl;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<temp[i][j]<<" ";
}
cout<<endl;
}
return sum;
}
int main(){
//输入一个二维数组
cin>>n;
int **p=new int*[n];
for(int i=0;i<n;i++){
p[i]=new int[n];
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>p[i][j];
}
}
int sum=prime(p,0);//返回最短距离
cout<<"最短距离:"<<sum<<endl;
return 0;
}
结果: