当前位置:首页 » 操作系统 » 普里姆算法例题

普里姆算法例题

发布时间: 2023-04-19 08:11:21

A. 普里姆算法

你要先明白prim算法的原理,明白原理后看下面的程序要点:

1.程序实现的时候将点分成两部分,加入集合的和没有加入集合的;
2.每次从没有加入集合中找点;
3.对所有没有加入到集合中的点中,找一个边权最小的;
4.将边权最小的点加入集合中,并且修改和加入点相连的没有加入的点的权,重复第2步,知道所有的点都加入到集合中;

B. 已知一个无向图如下,分别用普里姆和克鲁斯卡尔算法生成最小生成树(假设以1为起点,试画出构造过程)。

1)普里姆算法思想
从图中任意取出一个顶点, 把它当成棵树,然后从与这棵树相接的边中选取一条最短(权值最小)的边, 并将这条边及其所连接的顶点也并入这棵树中,此时得到了一棵有两个顶点的树。然后从与这棵树相接的边中选取一条最短的边,并将这条边及其所连顶点并入当前树中,得到一棵有3个顶点的树。以此类推,直到图中所有顶点都被并入树中为止,此时得到的生成树就是最小生成树。
2)克鲁斯卡尔算法思想
先将边中的权值从小到大排序,每次找出候选边中权值最小的边,就将该边并入生成树中。重复此过程直到所有边都被检测完为止。其中要注意的是克鲁斯卡尔算法需要用到并查集,以此来判断接下来要并入的边是否会和已并入的边构成回路。这两个图分别用普里姆和克鲁斯卡尔生成的最小生成树见图。


需要注意的是,在接下来要并入的最小权值不唯一的情况下,可以选取的边是不唯一的,所以其最小生成树也不唯一。(纯手打,望采纳,谢谢。)

C. 请问下下面这些关于数据结构的题怎么做,请给出具体的解题过程

  1. 直接插入排序第四趟结果:25 35 45 48 48 78 52

    简单选择排序第四趟结果:25 35 45 48 48 78 52


猜哪穗 2.孩子兄弟表示法:


我感觉应该都正确,费了我穗卜好大的劲才弄上去,一定采纳哈,谢谢

D. 根据Prim算法,求图示的最小代价生成树。 设①为起点,要求画出构造过程。

#include <iostream>
#include <iomanip>
using namespace std;

#define MAX_VERTEX_NUM 10 //最大顶点个数
#define INFINITY 1000 //定义最大值为1000
typedef char VerType;//定点向量
typedef int VRType;//定点之间的关系(即权值)
typedef struct
{
VerType vexs[MAX_VERTEX_NUM]; //顶点向量
int arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; //邻接矩阵
int vexnum,arcnum; //图的当前顶点数和弧数
}mgraph, * MGraph;
typedef struct
{
VerType adjvex;
VRType lowcost;
}closedge[MAX_VERTEX_NUM];//记录从顶点集U到V-U的代价最小的边的辅助数组定义

//初始化图
void init_mgraph(MGraph &g)
{
g=(MGraph)malloc(sizeof(mgraph));
g->vexnum=0;
g->arcnum=0;
for(int i=0;i<MAX_VERTEX_NUM;i++)
g->vexs[i]=0;
for(i=0;i<MAX_VERTEX_NUM;i++)
for(int j=0;j<MAX_VERTEX_NUM;j++)
g->arcs[i][j]=INFINITY;
}

void add_vexs(MGraph &g) //增加顶点
{
cout<<"请输入顶点的个数:"<<endl;
cin>>g->vexnum;
cout<<"请输入顶点的值"<<endl;
for(int i=0;i<g->vexnum;i++)
{
cin>>g->vexs[i];
}
}
void add_arcs(MGraph &g) //增加边
{
cout<<"请输入边的个数:"<<endl;
cin>>g->arcnum;
VerType ch1,ch2;
巧消int weight;
int row,col;

for(int i=0;i<g->arcnum;i++)
{
cin>>ch1>>ch2>>weight;
for(int j=0;j<g->vexnum;j++)
{
if(g->vexs[j]==ch1)
{
row=j;
}
if(g->vexs[j]==ch2)
{
col=j;
}
}
g->arcs[row][col]=weight; //有向带权图只需把1改为weight
g->arcs[col][row]=weight;
}
}
void creat_mgraph(MGraph &g) //创建图
{
add_vexs(g); //增加顶点
add_arcs(g); //增加边
}

void print_mgraph(MGraph &g) //打印图
孝做知胡明{
for(int i=0;i<g->vexnum;i++)
cout<<" "<<g->vexs[i]<<" ";
cout<<endl;
for(i=0;i<g->vexnum;i++)
{
cout<<g->vexs[i];
for(int j=0;j<g->vexnum;j++)
{
cout<<setw(5)<<g->arcs[i][j]<<" ";
}
cout<<endl;
}
}

//返回顶点v在顶点向量中的位置
int LocateVex(MGraph &g, VerType v)
{
int i;
for(i = 0; v != g->vexs[i] && i < g->vexnum; i++)
;
if(i >= g->vexnum)
return -1;
return i;
}
//求出T的下一个节点,第k节点
int minimun(MGraph &g, closedge closedge)
{
int min=INFINITY,k=0,i;
for(i=0;i<g->vexnum;i++)
{
if(closedge[i].lowcost != 0 && closedge[i].lowcost < min)
{
min = closedge[i].lowcost;
k = i;
}
}
return k;
}
//普里姆算法
void MiniSpanTree_Prim(MGraph &g, VerType u) //普里姆算法从顶点u出发构造G的最小生成树T,输出T的各条边。
{
closedge closedge;

int i,j;
int k=LocateVex(g,u);
for(j=0;j<g->vexnum;j++) //辅助数组初始化
{
if(j!=k)
{
closedge[j].adjvex=u;
closedge[j].lowcost=g->arcs[k][j];
}
}
closedge[k].lowcost = 0; //初始,U={u}

for(i=1;i<g->vexnum;i++) //选择其余g.vexnum-1个顶点
{
k=minimun(g,closedge); //求出T的下一个节点,第k节点
cout<<closedge[k].adjvex<<" "<<g->vexs[k]<<" "<<closedge[k].lowcost<<endl; //输出生成树的边
closedge[k].lowcost=0; //第k顶点并入U集

for(j=0;j<g->vexnum;j++)
{
if(g->arcs[k][j] < closedge[j].lowcost) //新顶点并入集后,选择新的边,将小的边放到辅助数组中
{
closedge[j].adjvex = g->vexs[k];
closedge[j].lowcost = g->arcs[k][j];
}
}
}
}//MiniSpanTree_Prim

int main()
{
MGraph G;
init_mgraph(G); //初始化图
creat_mgraph(G); //创建图
print_mgraph(G); //打印图
MiniSpanTree_Prim(G,G->vexs[0]); //最小生成树

return 0;
}

E. 这是一道数据结构问题,问题如下:对于如下图所示的带权无向图,给出利用普利姆(Prim)算法和克鲁斯卡尔

自己按下面的先后过程画图即是生成过程;说雀雀明(i,j)是一条连接顶点i和j的一条边;
普利姆(Prim)算法:从顶点0开始顷世早构造
(0,1),(0,2),(1,2),(2,5),(5,4)
克鲁斯卡尔算法:
(0,1),(0,2),(返或1,2),(4,5),(2,5)

F. 普里姆算法(Prime)

普利姆(Prim)算法求最小生成树,也就是在包含 n 个顶点的连通图中,找出只有(n-1)条边包含所有 n 个顶点的连通子图,也就是所谓的极小连通子图

普利坦闹仔姆的算法如下:

1. 有七个站点 A,B,C,D,E,F,G,现在需要修线路把弯哗七个站点联通

2. 各个站点的距离用边线表示(权),比如 A->C 为7公里

问: 如让汪何修线路使各个站点都能联通, 同时修的线路里程最短?

G. 用普里姆算法求最小生成树(C++)

求最小生成树的谱里姆算法
#include <iostream>
using namespace std;

const int n=6;
const int e=10;
class edgeset
{public :
int front;
int end;
int weight;};

class tree
{public :
int s[n+1][n+1];
edgeset ct[n+1];

void prim(tree &t)
{
int i,j,k,min,t1,m,w;
for(i=1;i<n;i++)
{t.ct[i].front=1;
t.ct[i].end=i+1;
t.ct[i].weight=t.s[1][i+1];}

for(k=2;k<=n;k++)
{min=32767;
m=k-1;

for(j=k-1;j<n;j++)
if(t.ct[j].weight<min)
{min=t.ct[j].weight;
m=j;}
edgeset temp=t.ct[k-1];
t.ct[k-1]=t.ct[m];
t.ct[m]=temp;
j=t.ct[k-1].end;
for(i=k;i<n;i++)
{t1=t.ct[i].end;
w=t.s[j][t1];
if(w<t.ct[i].weight)
{t.ct[i].weight=w;
t.ct[i].front=j;}}}}
};

void main ()
{int j,w;tree t;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i==j)t.s[i][j]=0;
else t.s[i][j]=32767;

for(int k=1;k<=e;k++)
{cout<<"输入一条边及边上的权值 ";
cin>>i>>j>>w;
cout<<endl;
t.s[i][j]=w;
t.s[j][i]=w;}

t.prim(t);
for(i=1;i<n;i++)
{cout<<t.ct[i].front<<" "<<t.ct[i].end<<" "<<t.ct[i].weight<<endl;}
}
我们的实验上机做了的
运行结果
输入一条边及边上的权值 1 2 6

输入一条边及边上的权值 1 3 1

输入一条边及边上的权值 1 4 6

输入一条边及边上的权值 2 3 5

输入一条边及边上的权值 2 5 3

输入一条边及边上的权值 3 4 7

输入一条边及边上的权值 3 5 5

输入一条边及边上的权值 3 6 4

输入一条边及边上的权值 4 6 2

输入一条边及边上的权值 5 6 6

1 3 1
3 6 4
6 4 2
3 5 5
5 2 3
Press any key to continue
你有的图不一样就该顶点和边就是
const int n=6;
const int e=10;

H. 在N个城市之间铺设煤气管道,只需架设N-1条线路即可,如何以最低的经济代价铺设.(普里姆算法)

此题可以用最小生成树的办法解决即普里姆如纳算法:把N个城市看作N个顶点,把可以铺设管道的两个城市间用线连起来,把相连的两个城市之间的距离作为这一条边的权(假设所有管道的单位造价相同).把所有边的权按照大小排列起来,先选权最小的边的两个顶点纳入集合S,再选第二条边,把与这条边关联的顶点纳入S,但前提是所选的边不能与前面所选的边构成回路,就这样依次选取.若有权相同的n条边则任选一条,但前提是所选的边不能与前面所选的边构成回路.接下来选的时候还是选n条边中的一条前提依然和前面相同.当所粗察选的路的岩橡茄个数为N-1时就停止.此时的线路即为最优的铺设线路.

热点内容
求中点编程 发布:2025-05-18 01:03:14 浏览:840
安卓pay是什么 发布:2025-05-18 01:02:27 浏览:747
免费手游挂机脚本 发布:2025-05-18 00:55:43 浏览:354
sd卡手机存储系统存储 发布:2025-05-18 00:55:28 浏览:637
pythonlistintstr 发布:2025-05-18 00:48:18 浏览:604
轻应用缓存 发布:2025-05-18 00:31:02 浏览:252
鸟存储空气 发布:2025-05-18 00:20:24 浏览:201
linux刻录iso 发布:2025-05-18 00:16:15 浏览:663
php动态参数 发布:2025-05-18 00:12:05 浏览:425
安卓应用上传 发布:2025-05-18 00:11:57 浏览:803