最小生成树:构造的连通网的最小代价生成树
普里姆(prim)算法
prim算法详解
https://www.cnblogs.com/skywang12345/p/3711507.html
算法详解:
如图所示无向图
prim算法是任意找一点,取与这一点相关的所有边中权值最小的边,这条边又开辟了一块新结点,依次操作,直到n个结点连通,且只有(n-1)条边;
假设n=9,当前取的边数为total=0,取的第一个点为v0点,定义一个优先队列Q(排序方式是由小到大),与v0相连的边有两条,分别加入队列,Q中加入两格元素(10,11);弹出10,total=1,并解锁了v1,与v1顶点相连的边有16,12,18,依次加入Q(11,12,16,18);弹出11,,total=2,并解锁了v5,与v5顶点相连的边有26,17(11已经遍历过了,故不再记录),依次加入队列Q(12,16,17,18,26);弹出12,total=3,解锁新v8,与v8相连的边有8,21,依次加入队列……………(按上述方法循环下去,直到total==n-1结束,此时,所有权值的和为最低)
弹出的边一定是当前解锁的边中权值最低的边;
邻接矩阵
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstdlib>
using namespace std;
#define INF 1000;
const int maxn=110;
struct Graph
{
int arc[maxn][maxn];
int total_vertex,total_edge;
};
double random(double start,double end)//随机数产生器
{
return start+(end-start)*rand()/(RAND_MAX+1.0);
}
void Initial(Graph &G)//一定要用&,不然无法改变相应实参的值,会出错
{
for(int i=0;i<G.total_vertex;i++)
{
for(int j=0;j<G.total_vertex;j++)
{
if(j==i)
G.arc[i][j]=0;
else
G.arc[i][j]=INF;
}
}
}
void Connect(Graph &G)//一定要用&,不然无法改变相应实参的值,会出错
{
printf("Input %d pair of (v1,v2) and weight:\n",G.total_edge);
for(int i=0;i<G.total_edge;i++)
{
int v1,v2;
int weight;
scanf("%d%d",&v1,&v2);
scanf("%d",&weight);
G.arc[v1][v2]=weight;
G.arc[v2][v1]=weight;
}
}
void Create_Graph(Graph &G)//一定要用&,不然无法改变相应实参的值,会出错
{
printf("Input the total of the vertex and the edge:\n");
scanf("%d%d",&G.total_vertex,&G.total_edge);
Initial(G);
Connect(G);
}
void Mst_Prim(Graph G)
{
int adjvex[G.total_vertex];
int lower_cost[G.total_vertex];
srand(unsigned(time(0)));
int first=random(0,G.total_vertex);//随机产生0~G.total_vertex 中的一个数
for(int i=0;i<G.total_vertex;i++)
{
adjvex[i]=first;
lower_cost[i]=G.arc[first][i];
}
for(int i=1;i<G.total_vertex;i++)//只需G.total_vertex-1条边即可;
{
int min=INF;
int k=0,j=0;
while(j<G.total_vertex)
{
if(lower_cost[j]!=0&&lower_cost[j]<min)
{
min=lower_cost[j];
k=j;
}
j++;
}
printf("(%d,%d)\n",adjvex[k],k);
lower_cost[k]=0;
for(int j=0;j<G.total_vertex;j++)
{
if(lower_cost[j]!=0&&lower_cost[j]>G.arc[k][j])
{
lower_cost[j]=G.arc[k][j];
adjvex[j]=k;
}
}
}
}
int main()
{
Graph G;
Create_Graph(G);
Mst_Prim(G);
return 0;
}
/*
input:
9 15
0 1 10
0 5 11
1 2 18
1 8 12
1 6 16
2 8 8
2 3 22
3 4 20
3 6 24
3 7 16
3 8 21
4 5 26
4 7 7
5 6 17
6 7 19
output://first=0的情况下
(0,1)
(0,5)
(1,8)
(8,2)
(1,6)
(6,7)
(7,4)
(7,3)
*/
prim算法 C语言详解
http://www.cnblogs.com/skywang12345/p/3711506.html
邻接表
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<map>
#include<ctime>
using namespace std;
#define INF (~(0x1<<31))//相当于定义了一个很大的值INF
const int maxn=110;
double random(double start,double end)//随机数发生器
{
return start+(end-start)*rand()/(RAND_MAX+1.0);
}
map<int ,int >vex_p;
map<int ,int >p_value;
struct Edge_Node
{
int ivex;
int weight;
Edge_Node *next_edge;
};
struct Vex_Node
{
int data;
Edge_Node *first_edge;
};
struct Graph
{
int total_vex,total_edge;
Vex_Node vexs[maxn];
};
void Link_List(Edge_Node *list,Edge_Node *node)
{
Edge_Node *p=list;
while(p->next_edge)
p=p->next_edge;
p->next_edge=node;
}
Graph *Create_Graph()
{
Graph *G=(Graph *)malloc(sizeof(Graph));
printf("Input the total of vex and edge:\n");
scanf("%d%d",&G->total_vex,&G->total_edge);
printf("Input %d value of vex:\n",G->total_vex);
for(int i=0;i<G->total_vex;i++)
{
int value;
scanf("%d",&value);
G->vexs[i].data=value;
G->vexs[i].first_edge=NULL;
vex_p[value]=i;
p_value[i]=value;
}
printf("Input %d pair of (v1,v2) and weight:\n",G->total_edge);
for(int i=0;i<G->total_edge;i++)
{
int v1,v2,weight;
scanf("%d%d",&v1,&v2);
scanf("%d",&weight);
int p1=vex_p[v1];
int p2=vex_p[v2];
Edge_Node *node1=(Edge_Node*)malloc(sizeof(Edge_Node));
node1->ivex=p2;
node1->weight=weight;
node1->next_edge=NULL;
if(G->vexs[p1].first_edge==NULL)
G->vexs[p1].first_edge=node1;
else
Link_List(G->vexs[p1].first_edge,node1);
Edge_Node *node2=(Edge_Node *)malloc(sizeof(Edge_Node));
node2->ivex=p1;
node2->weight=weight;
node2->next_edge=NULL;
if(G->vexs[p2].first_edge==NULL)
G->vexs[p2].first_edge=node2;
else
Link_List(G->vexs[p2].first_edge,node2);
}
return G;
}
int Get_Weight(Graph G,int start,int end)
{
Edge_Node *node;
if(start==end)
return 0;
node=G.vexs[start].first_edge;
while(node!=NULL)
{
if(node->ivex==end)
return node->weight;
node=node->next_edge;
}
return INF;
}
void Prim(Graph G,int start)
{
int vexNum=G.total_vex;
int vexs[vexNum];
int lower_cost[vexNum];
for(int i=0;i<vexNum;i++)
{
vexs[i]=start;
lower_cost[i]=Get_Weight(G,start,i);
}
for(int i=1;i<vexNum;i++)
{
int min=INF;
int j=0,k=0;
while(j<vexNum)
{
if(lower_cost[j]!=0&&lower_cost[j]<min)
{
min=lower_cost[j];
k=j;
}
j++;
}
printf("(%d,%d)\n",p_value[vexs[k]],p_value[k]);
lower_cost[k]=0;
for(j=0;j<vexNum;j++)
{
if(lower_cost[j]!=0&&Get_Weight(G,k,j)<lower_cost[j])
{
lower_cost[j]=Get_Weight(G,k,j);
vexs[j]=k;
}
}
}
}
void Print(Graph *G)
{
for(int i=0;i<G->total_vex;i++)
{
printf("%d->",G->vexs[i].data);
Edge_Node *node=G->vexs[i].first_edge;
while(node!=NULL)
{
printf("%d(%d)->",p_value[node->ivex],node->weight);
node=node->next_edge;
}
printf("NULL\n");
}
}
int main()
{
Graph *G;
int start;
G=Create_Graph();
//Print(G);
srand(unsigned(time(0)));
start=random(0,G->total_vex-1);
Prim(*G,start);
delete G;
return 0;
}