最小生成树问题————Prim算法
实现一个程序用最小成本将若干个城市进行联网
要求
给出将两个城市进行联通的成本。要求使用最小成本将所有城市进行联网
输入
N(表示城市数目)
接下来是若干组三元组(a,b,x)表示a城市到b城市联通的成本为x,以-1为结尾
输出
给出N-1个二元组(a,b)表示联网时需要将a和b连接起来
最小生成树问题,采用Prim算法,在图上任取一点为一根树。
把该点加入终点集遍历图中所有与树相连的边,取其中权值最小的边,把该边加入边集,与之对应的不在终点集中的点加入终点集。
递归上述操作让一个小树长大,当边集中的元素为N-1时结束。
#include "iostream"
using namespace std;
int a[1000][3];//三元组
int b[100];//终点集
int c[200];//边集
int count;//三元组数量
int n;//城市数量
int main()
{
void prim(int m);
int i;
cin>>n;
for(i=0;i<1000;i++)
{
cin>>a[i][0];
if(a[i][0]==-1) //输入结束
break;
cin>>a[i][1];
cin>>a[i][2];
}
count=i;
b[0]=a[0][0];//初始化,任一点放入边集
prim(0);//实参为 边集内已有边数
for(i=0;i<2*(n-1);i=i+2)
{
cout<<c[i]<<" "<<c[i+1]<<endl;
}
return 0;
}
void prim(int m)
{
if(m==n) //边集内有n-1条边结束
{
return;
}
/*cout<<"终点集:";
for(int i=0;i<=m;i++)
{
cout<<b[i];
}
cout<<endl;*/
int k=0,min=10000,dj=0,ej=0,fj=0;
for(int i=0;i<=m;i++)
{
for(int j=0;j<count;j++) //二重循环,寻找与最小生成树相连的边
{
if(b[i]==a[j][0])
{
for(int cj=0;cj<=m;cj++) //对于边的两点都再终点集内的边过滤
{
if(a[j][1]==b[cj])
{
a[j][0]=0;
a[j][1]=0;
dj=1;
break;
}
}
if(dj==1)
{
dj=0;
continue;
}
if(a[j][2]<min) //不断选择权值最小的边 并记录此边在三元组中的位置
{
//cout<<"入集:"<<j<<" "<<a[j][2]<<endl;
ej=j;
fj=1;
min=a[j][2];
}
}
if(b[i]==a[j][1])
{
for(int cj=0;cj<=m;cj++)
{
if(a[j][0]==b[cj])
{
a[j][0]=0;
a[j][1]=0;
dj=1;
break;
}
}
if(dj==1)
{
dj=0;
continue;
}
if(a[j][2]<min)
{
ej=j;
fj=0;
min=a[j][2];
}
}
}
}
b[m+1]=a[ej][fj]; //点、边收入终点集 边集 该三元组置0
c[2*m]=a[ej][0];
c[2*m+1]=a[ej][1];
a[ej][0]=0;
a[ej][1]=0;
prim(m+1); //m的值加一;
}