贪心算法---prim算法。
G=(V,E)-----V顶点集合,E为权值集合,
1)S={1}加入顶点集//例如第一个加入是1,i属于S,j属于V-S集合中找出C[i][j]最小的全职,此时将j加入S;
2)此时S集合中点数为2,j又在 V-S中取值。
3)循环找到最小的值,纪录点。知道找完为止。
4)这里要注意是找两个集合最近权值。
设计代码:
#include <iostream>
using namespace std;
#define Not 10000
//设计在这里Not表示为不通,就是没有改路
#define N 100
//最多有这么多点
int Graph[N][N];
int MinValue[N];
//表示为以N点为终点的最小权值
int MST[N];
//用来记录上面得到的最小权值的点
//设计一个的到最小权值的,这里是以start为起点
int prim(int length,int start)
{
for(int i=1;i<=length;++i)
{
//这里是以start起点,当然要把它排出去
if(i!=start)
{
//先记录第一次选择,start点附近的所有的值
MinValue[i]=Graph[start][i];
MST[i]=start;
//添加该点
}
}
MST[start]=0;
//表示加入了改点,start其实是起点
int min,sum=0;
int minid=0;
//sum用来记录最小的权值的
for(int i=1;i<=length;++i)
{
if(i!=start)
{
min=Not;
minid=0;
for(int j=1;j<=length;++j)
{
if(j!=start)
{
if(MinValue[j]<min&&MinValue[j]!=0)
{
min=MinValue[j];
minid=j;
}
}
//找到最小值,而且用minid记录它的位置;
}
//现在可以在此打印
cout<<"V"<<MST[minid]<<"到"<<"-v"<<minid<<"="<<min<<endl;
sum+=min;
//加上此时的最小权值
//将此时对应的最小的权值设为0,表示它已经走过了
MinValue[minid]=0;
for(int j=1;j<=length;++j)
{
if(j!=start)
{
if(Graph[minid][j]<MinValue[j])
{
MinValue[j]=Graph[minid][j];
MST[j]=minid;
}
}
}
}
}
return sum;
}
int main(int argc, const char * argv[]) {
// insert code here...
std::cout << "算法请输入顶点的个数:\n";
int n;
cin>>n;
int start;
cout<<"输入您开始的点是";
cin>>start;
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
Graph[i][j]=Not;
//进行初始化
}
cout<<"构建图形:\n";
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n;++j)
{
if(i==j) Graph[i][j]=Not;
else{
cout<<"10000表示为不可达他是无限大的,其他的输入正常的点:("<<i<<","<<j<<"):";
cin>>Graph[i][j];
}
}
}
int sum=prim(n, start);
cout<<sum<<endl;
return 0;
}