1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<iostream>
4 #define MAX_VERTEX_NUM 20
5 #define OK 1
6 #define ERROR 0
7 #define MAX 1000
8 using namespace std;
9 typedef struct Arcell
10 {
11 double adj;
12 }Arcell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
13 typedef struct
14 {
15 char vexs[MAX_VERTEX_NUM]; //节点数组
16 AdjMatrix arcs; //邻接矩阵
17 int vexnum, arcnum; //图的当前节点数和弧数
18 }MGraph;
19 typedef struct Pnode //用于普利姆算法
20 {
21 char adjvex; //节点
22 double lowcost; //权值
23 }Pnode,Closedge[MAX_VERTEX_NUM]; //记录顶点集U到V-U的代价最小的边的辅助数组定义
24 typedef struct Knode //用于算法中存储一条边及其对应的2个节点
25 {
26 char ch1; //节点1
27 char ch2; //节点2
28 double value;//权值
29 }Knode,Dgevalue[MAX_VERTEX_NUM];
30 //-----------------------------------------------------------------------------------
31 int CreateUDG(MGraph & G,Dgevalue & dgevalue);
32 int LocateVex(MGraph G,char ch);
33 int Minimum(MGraph G,Closedge closedge);
34 void MiniSpanTree_PRIM(MGraph G,char u);
35 void Sortdge(Dgevalue & dgevalue,MGraph G);
36 //-----------------------------------------------------------------------------------
37 int CreateUDG(MGraph & G,Dgevalue & dgevalue) //构造无向加权图的邻接矩阵
38 {
39 int i,j,k;
40 cout<<"请输入图中节点个数和边/弧的条数:";
41 cin>>G.vexnum>>G.arcnum;
42 cout<<"请输入节点:";
43 for(i=0;i<G.vexnum;++i)
44 cin>>G.vexs[i];
45 for(i=0;i<G.vexnum;++i)//初始化数组
46 {
47 for(j=0;j<G.vexnum;++j)
48 {
49 G.arcs[i][j].adj=MAX;
50 }
51 }
52 cout<<"请输入一条边依附的定点及边的权值:"<<endl;
53 for(k=0;k<G.arcnum;++k)
54 {
55 cin >> dgevalue[k].ch1 >> dgevalue[k].ch2 >> dgevalue[k].value;
56 i = LocateVex(G,dgevalue[k].ch1 );
57 j = LocateVex(G,dgevalue[k].ch2 );
58 G.arcs[i][j].adj = dgevalue[k].value;
59 G.arcs[j][i].adj = G.arcs[i][j].adj;
60 }
61 return OK;
62 }
63 int LocateVex(MGraph G,char ch) //确定节点ch在图G.vexs中的位置
64 {
65 int a ;
66 for(int i=0; i<G.vexnum; i++)
67 {
68 if(G.vexs[i] == ch)
69 a=i;
70 }
71 return a;
72 }
73 //typedef struct Pnode //用于普利姆算法
74 //{
75 // char adjvex; //节点
76 // double lowcost; //权值
77 //}Pnode,Closedge[MAX_VERTEX_NUM]; //记录顶点集U到V-U的代价最小的边的辅助数组定义
78 void MiniSpanTree_PRIM(MGraph G,char u)//普利姆算法求最小生成树
79 {
80 int i,j,k;
81 Closedge closedge;
82 k = LocateVex(G,u);
83 for(j=0; j<G.vexnum; j++)
84 {
85 if(j != k)
86 {
87 closedge[j].adjvex = u;
88 closedge[j].lowcost = G.arcs[k][j].adj;
89 }
90 }
91 closedge[k].lowcost = 0;
92 for(i=1; i<G.vexnum; i++)
93 {
94 k = Minimum(G,closedge);
95 cout<<"("<<closedge[k].adjvex<<","<<G.vexs[k]<<","<<closedge[k].lowcost<<")"<<endl;
96 closedge[k].lowcost = 0;
97 for(j=0; j<G.vexnum; ++j)
98 {
99 if(G.arcs[k][j].adj < closedge[j].lowcost)
100 {
101 closedge[j].adjvex = G.vexs[k];
102 closedge[j].lowcost= G.arcs[k][j].adj;
103 }
104 }
105 }
106 }
107 int Minimum(MGraph G,Closedge closedge) //求closedge中权值最小的边,并返回其顶点在vexs中的位置
108 {
109 int i,j;
110 double k = 1000;
111 for(i=0; i<G.vexnum; i++)
112 {
113 if(closedge[i].lowcost != 0 && closedge[i].lowcost < k)
114 {
115 k = closedge[i].lowcost;
116 j = i;
117 }
118 }
119 return j;
120 }
121 void MiniSpanTree_KRSL(MGraph G,Dgevalue & dgevalue)//克鲁斯卡尔算法求最小生成树
122 {
123 int p1,p2,i,j;
124 int bj[MAX_VERTEX_NUM]; //标记数组
125 for(i=0; i<G.vexnum; i++) //标记数组初始化
126 bj[i]=i;
127 Sortdge(dgevalue,G);//将所有权值按从小到大排序
128 for(i=0; i<G.arcnum; i++)
129 {
130 p1 = bj[LocateVex(G,dgevalue[i].ch1)];
131 p2 = bj[LocateVex(G,dgevalue[i].ch2)];
132 if(p1 != p2)
133 {
134 cout<<"("<<dgevalue[i].ch1<<","<<dgevalue[i].ch2<<","<<dgevalue[i].value<<")"<<endl;
135 for(j=0; j<G.vexnum; j++)
136 {
137 if(bj[j] == p2)
138 bj[j] = p1;
139 }
140 }
141 }
142 }
143 void Sortdge(Dgevalue & dgevalue,MGraph G)//对dgevalue中各元素按权值按从小到大排序
144 {
145 int i,j;
146 double temp;
147 char ch1,ch2;
148 for(i=0; i<G.arcnum; i++)
149 {
150 for(j=i; j<G.arcnum; j++)
151 {
152 if(dgevalue[i].value > dgevalue[j].value)
153 {
154 temp = dgevalue[i].value;
155 dgevalue[i].value = dgevalue[j].value;
156 dgevalue[j].value = temp;
157 ch1 = dgevalue[i].ch1;
158 dgevalue[i].ch1 = dgevalue[j].ch1;
159 dgevalue[j].ch1 = ch1;
160 ch2 = dgevalue[i].ch2;
161 dgevalue[i].ch2 = dgevalue[j].ch2;
162 dgevalue[j].ch2 = ch2;
163 }
164 }
165 }
166 }
167 void main()
168 {
169 int i,j;
170 MGraph G;
171 char u;
172 Dgevalue dgevalue;
173 CreateUDG(G,dgevalue);
174 cout<<"图的邻接矩阵为:"<<endl;
175 for(i=0; i<G.vexnum; i++)
176 {
177 for(j=0; j<G.vexnum; j++)
178 cout << G.arcs[i][j].adj<<" ";
179 cout<<endl;
180 }
181 cout<<"=============普利姆算法===============\n";
182 cout<<"请输入起始点:";
183 cin>>u;
184 cout<<"构成最小代价生成树的边集为:\n";
185 MiniSpanTree_PRIM(G,u);
186 cout<<"============克鲁斯科尔算法=============\n";
187 cout<<"构成最小代价生成树的边集为:\n";
188 MiniSpanTree_KRSL(G,dgevalue);
189 }