Prim算法模版
//需包含头文件<vector>
//需要用到结构体
//需定义const常量INF为无穷大(const int INF = 0xffffff)
//需建立以动态数组为元素的一维数组此处为w[]
//需定义bool类型的数组intree[]来记录某点是否已加入所求点中
//需对数组mindist[]进行初始化,使mindist[]中每个元素都为无穷大
int Prim(int s) //s 为起点
{
int vex,addNode,tempMin; //vex 为所求根节点的第一次分支节点位置
//addNode 为满足条件要加入目标节点结合的点的位置
//tempMin 它负责记录所遍历的所有所求根节点的第一次分支节点的最小权值(对每个第一次分支节点的权值进行比较,取最小)
intree[s] = true;
for(unsigned int i = 0;i < w[s].size();i++) //把起点当作一个根节点,遍历起点的所有的第一次分支节点
{
vex = w[s][i].vex; //记录起点的每一个第一次分支节点位置
mindist[vex] = w[s][i].weight; //记录起点的每一个第一次分支节点的到起点的权值(mindist[]数组记录的是未加入所求点集的所有点到所求点集里的所有点的最小权值)
}
for(int nodeNum = 1;nodeNum <= N-1;nodeNum++) //对余下的所有点进行遍历
{
tempMin = INF;
for(int i = 1;i <= N;i++) //对所有点进行遍历
{
if(intree[i] == false && mindist[i] < tempMin) //判断第i点是否已经在所求点集里并且判断第i点到所求点集的权值是否为最小
{
tempMin = mindist[i]; //更新最小权值
addNode = i; //记录到所求点集最小权值的点的位置
}
}
intree[addNode] = true; //将具有到所求点集的最小权值的点放入所求点集
ans += tempMin; //对求得的最小权值相加
for(unsigned int i = 0;i < w[addNode].size();i++) //对新加入所求点集的点的第一次分支节点进行遍历
{
vex = w[addNode][i].vex; //记录新加入所求点集的点的第一次分支节点的位置
if(intree[vex] == false && w[addNode][i].weight < mindist[vex]) //对未加入所求点集的点到所求点集的权值进行更新,使未加入所求点集的点到所求点集的权值最小
mindist[vex] = w[addNode][i].weight;
}
}
return ans; //返回最小权值之和
} //所求点集为最小生成树
Prim算法作用:
例:修N个村庄的路,每个村庄间的路都有不同的经费,要修N-1条路使得经费最小,求最小经费
例题HDU_1233:
#include <cstdio>
#include <vector>
using namespace std;
struct Weight
{
int vex,weight;
Weight(int vex = 0,int weight = 0):vex(vex),weight(weight){}
};
const int max_num_weight = 5005;
const int max_country = 105;
const int INF = 0xffffff;
int N;
int ans;
int rank[max_country];
int mindist[max_country];
bool intree[max_country];
vector<Weight> w[max_country];
void Init()
{
ans = 0;
for(int i = 1;i <= N;i++)
{
w[i].clear();
intree[i] = false;
mindist[i] = INF;
}
return ;
}
int Prim(int s)
{
int vex,addNode,tempMin;
intree[s] = true;
for(unsigned int i = 0;i < w[s].size();i++)
{
vex = w[s][i].vex;
mindist[vex] = w[s][i].weight;
}
for(int nodeNum = 1;nodeNum <= N-1;nodeNum++)
{
tempMin = INF;
for(int i = 1;i <= N;i++)
{
if(intree[i] == false && mindist[i] < tempMin)
{
tempMin = mindist[i];
addNode = i;
}
}
intree[addNode] = true;
ans += tempMin;
for(unsigned int i = 0;i < w[addNode].size();i++)
{
vex = w[addNode][i].vex;
if(intree[vex] == false && w[addNode][i].weight < mindist[vex])
mindist[vex] = w[addNode][i].weight;
}
}
return ans;
}
int main()
{
while(scanf("%d",&N)&&N)
{
Init();
int v1,v2,weight;
for(int i = 0;i < N*(N-1)/2;i++)
{
scanf("%d%d%d",&v1,&v2,&weight);
w[v1].push_back(Weight(v2,weight));
w[v2].push_back(Weight(v1,weight));
}
Prim(1);
printf("%d\n",ans);
}
return 0;
}