最小生成树prim模板
程序员文章站
2022-06-16 08:12:11
...
1.模板一
此段模板取自<挑战程序设计竞赛>p106-107
//int cost[INF][INF];//边
//int used[INF];
//int mincost[INF];//X到节点v的最小值
//int v;
int prim()
{
for (int i = 0; i < V; i += 1){
mincost[i] = INF;
used[i] = false;
}
mincost[0] = 0;
int res = 0;
while (1){
int v = -1;
//从不属于X的顶点中找到从X到其权值最小的顶点
for (int i = 0; i < V; i += 1){
if(!used[i] && (v == -1 || mincost[i] < mincost[v]))
v = i;
}
if(v == -1) break;
used[v] = true;
res += mincost[v];
//在此顶点基础上对X到其他顶点的最小值进行更新
for (int i = 0; i < V; i += 1){
mincost[j] = min(mincost[j],cost[v][j]);
}
}
return res;
}
2.模板二
对以上模板进行优化,利用堆存储每个节点,复杂度可以达到O(ElogV)
//int V;
//int ans;
//int mincost[MAXN];
//int used[MAXN];
//struct edge{
//int to,cost;
//edge (){}
//edge (int to,int cost):to(to),cost(cost){}
//};
//vector <edge> G[MAXN];//存放从i出发的边
//typedef pair<int,int> P;//first存放距离,second存放节点
//priority_queue<P,vector<P>,greater<P>> que;
void prim()
{
//初始化
memset(used,0,sizeof(used));
fill(mincost,mincost+V,INF);
ans = 0;
que.push(P(0,0));
while (!que.empty()){
//取最短边
P p = que.top();
que.pop();
int d = p.first,v = p.second;
if (used[v]) continue;
used[v] = 1;
ans += d;
//以最短边的节点为基础,更新最短距离
for (int i = 0; i < G[v].size(); i += 1){
edge e = G [v][i];
if ((mincost[e.to] > e.cost) && !used[i]){
mincost[e.to] = e.cost;
que.push(P(mincost[e.to],e.to));
}
}
}
printf("%d\n",ans);
}