1 #include <iostream>
2 #include <algorithm>
3
4 using namespace std;
5 const int MaxNum = 100;
6 const int INF = 99999;
7 typedef struct srcNode {
8 int Vem;
9 struct srcNode * next;
10 } srcNode;
11
12 typedef struct vNode {
13 char data;
14 srcNode *src;
15 } vNode;
16
17 typedef struct GNode {
18 int vNum, srcNum;
19 vNode vNodeList[MaxNum];
20 } Graph, GNode;
21
22
23 /**
24 *BFS
25 */
26 void BFS(Graph *G) {
27 // 广度优先遍历需要维护一个队列
28 int v[MaxNum*MaxNum];
29 int front = -1, rear = -1;
30 bool visited[MaxNum];
31 for(int i=0; i<G->vNum; ++i) {
32 visited[i] = false;
33 }
34 v[++rear] = 0;
35 while(rear!=front) {
36 int vnow = v[++front];
37 if(!visited[vnow]) {
38 // 访问
39 cout<<G->vNodeList[vnow].data<<endl;
40 visited[vnow] = true;
41 srcNode *p = G->vNodeList[vnow].src;
42 while(p) {
43 v[++rear] = p->Vem;
44 p = p->next;
45 }
46
47 }
48 }
49 }
50
51 /**
52 *DFS
53 */
54 void DFS(Graph *G) {
55 int stack[MaxNum*MaxNum];
56 int top = -1;
57 bool visited[G->vNum];
58 for(int i=0; i<G->vNum; ++i) {
59 visited[i] = false;
60 }
61
62 stack[++top] = 0;
63 while(top!=-1) {
64 int vnow = stack[top--];
65 if(!visited[vnow]) {
66 cout<<G->vNodeList[vnow].data<<endl;
67 visited[vnow] = true;
68 srcNode *p = G->vNodeList[vnow].src;
69 while(p) {
70 stack[++top] = p->Vem;
71 p = p->next;
72 }
73 }
74 }
75 }
76
77 /**
78 *DFS递归遍历
79 */
80 bool isvisited[MaxNum*MaxNum]= {0};
81 void DFS(Graph *G, int v) {
82 cout<<G->vNodeList[v].data<<endl;
83 isvisited[v] = true;
84
85 srcNode *p = G->vNodeList[v].src;
86 while(p) {
87 if(!isvisited[p->Vem]) {
88 DFS(G, p->Vem);
89 }
90 p = p->next;
91 }
92 }
93
94 /**
95 *构造图的邻接链表
96 */
97 Graph *createGraph(char v[], int src[][6], int n) {
98 Graph *G = new Graph();
99 G->srcNum = 7;
100 G->vNum = 6;
101 for(int i=0; i<n; i++) {
102 G->vNodeList[i].data = v[i];
103 G->vNodeList[i].src = NULL;
104
105 for(int j=0; j<n; j++) {
106 if(src[i][j] != INF) {
107 srcNode *srcNow = new srcNode();
108 srcNow->Vem = j;
109 srcNow->next = G->vNodeList[i].src;
110 G->vNodeList[i].src = srcNow;
111 }
112 }
113 }
114 return G;
115 }
116
117
118 /**
119 *最小生成树
120 */
121 void prime(Graph *G, int src[][6]) {
122 // 维护两个数组
123 bool isVisited[G->vNum];
124 // 就是结果集
125 int parents[G->vNum];
126
127 // 初始化数组
128 for(int i=0; i<G->vNum; i++) {
129 isVisited[i] = false;
130 parents[i] = -1;
131 }
132
133 isVisited[0] = true;
134 int n=1;
135 while(n<G->vNum) {
136 int minL = INF;
137 //未访问的节点和已经访问的节点,这两点构成的边
138 int unvisited, visited;
139 for(int i=0; i<G->vNum; ++i) {
140 if(isVisited[i]) {
141 visited = i;
142 for(int j=0; j<G->vNum; ++j) {
143 if(!isVisited[j] && src[i][j] < minL) {
144 minL = src[i][j];
145 unvisited = j;
146 }
147 }
148 }
149
150 }
151
152 isVisited[unvisited] = true;
153 parents[unvisited] = visited;
154 n++;
155 }
156
157 // 输出树
158 for(int i=0; i<G->vNum; i++) {
159 cout<<i<<":"<<parents[i]<<endl;
160 }
161
162 }
163
164 /**
165 *Kruskal
166 */
167 //点边对
168 typedef struct VS {
169 int x, y;
170 int length;
171 } VS;
172 int com(VS vs1, VS vs2) {
173 return vs1.length>vs2.length;
174 }
175 //讲边按照长度进行排序
176 int VSsort(VS vsarray[], int src[][6], int vNum) {
177 int top = -1;
178 // 将所有节点封装成点边对,装入数组
179 for(int i=0; i<vNum; ++i) {
180 for(int j=0; j<vNum; ++j) {
181 if(src[i][j] != INF) {
182 VS vsnode;
183 vsnode.x = i;
184 vsnode.y = j;
185 vsnode.length = src[i][j];
186 vsarray[++top] = vsnode;
187 }
188 }
189 }
190 sort(vsarray, vsarray+top+1, com);
191 return top;
192 }
193
194 int findRoot(int v, int parents[]) {
195 if(parents[v] == -1) {
196 return v;
197 }
198 return findRoot(parents[v], parents);
199 }
200
201 bool unionV(int v1, int v2, int parents[]) {
202 int v1root = findRoot(v1, parents);
203 int v2root = findRoot(v2, parents);
204 if(v1root == v2root) {
205 return false;
206 }
207 parents[v1root] = v2root;
208 return true;
209 }
210
211 void Kruskal(int src[][6], int vNum) {
212 VS vsArray[MaxNum];
213 int top = VSsort(vsArray, src, vNum);
214 //并查集 ,并非结果集
215 int parents[vNum];
216 int result[vNum];
217 for(int i=0; i<vNum; ++i) {
218 parents[i] = -1;
219 result[i] = -1;
220 }
221
222 int n=0;
223 while(n < vNum-1) {
224 VS vsnode = vsArray[top--];
225 if(unionV(vsnode.x, vsnode.y, parents)) {
226 result[vsnode.x] = vsnode.y;
227 n++;
228 }
229 }
230
231 // 输出树
232 for(int i=0; i<vNum; i++) {
233 cout<<i<<":"<<result[i]<<endl;
234 }
235 }
236 /**
237 *多源最短路径
238 */
239 void flyoed(int src[][6], int origition, int destination) {
240 int length[6][6];
241 int parents[6][6];
242 // 备份路径长度,不能在原来上边更改
243 for(int i=0; i<6; i++) {
244 for(int j=0; j<6; ++j) {
245 length[i][j] = src[i][j];
246 parents[i][j] = j;
247 }
248
249 }
250
251 for(int i=0; i<6; i++) {
252 for(int j=0; j<6; j++) {
253 for(int k=0; k<6; k++) {
254 if((length[j][i] + length[i][k]) < length[j][k]) {
255 length[j][k] = (length[j][i] + length[i][k]);
256 parents[j][k] = parents[j][i];
257 }
258 }
259 }
260 }
261 cout<<length[origition][destination]<<endl;
262 cout<<origition<<" ";
263 int ori = origition;
264 while(ori != destination) {
265 cout<<parents[ori][destination]<<" ";
266 ori = parents[ori][destination];
267 }
268
269 }
270 /**
271 *单源最短路径
272 */
273 void Dijkstra(int src[][6], int origition, int destination) {
274 int path[6];
275 // 表示到目标点距离
276 int length[6];
277 bool isvisited[6];
278 for(int i=0; i<6; i++) {
279 path[i] = -1;
280 length[i] = src[i][destination];
281 isvisited[i] = false;
282 }
283 isvisited[destination] = true;
284 for(int i=0; i<6; i++) {
285 int nowShortestNode = destination;
286 // 从未收录的点中找一个到目标点距离最小的
287 for(int j=0; j<6; j++){
288 if(!isvisited[j] && length[j] < length[nowShortestNode]){
289 nowShortestNode = j;
290 }
291 }
292 isvisited[nowShortestNode] = true;
293 // 刷新其他顶点经过这个最小的点,到目标顶点的距离
294 for(int j=0; j<6; j++){
295 if(!isvisited[j] && (src[j][nowShortestNode] +length[nowShortestNode])< length[j]){
296 length[j] = src[j][nowShortestNode] +length[nowShortestNode];
297 path[j] = nowShortestNode;
298 }
299 }
300
301 }
302
303 // 输出路径
304 cout<<length[origition]<<endl;
305 int p = origition;
306 cout<<p<<" ";
307 while(path[p] != -1){
308 cout<<path[p]<<" ";
309 p = path[p];
310 }
311 cout<<destination;
312
313 }
314 void show(Graph *G) {
315 for(int i=0; i<G->vNum; i++) {
316 srcNode *p = G->vNodeList[i].src;
317 while(p) {
318 cout<<G->vNodeList[p->Vem].data<<" ";
319 p = p->next;
320 }
321 cout<<endl;
322 }
323 }
324
325 int main() {
326 char v[]= {'a', 'b', 'c', 'd', 'e', 'f'};
327 int src[6][6] = {
328
329 { INF, 6,INF,INF, 7,INF},
330 { 6,INF, 2, 3,INF, 5 },
331 { INF, 2,INF,INF, 1, 5 },
332 { INF, 3,INF,INF,INF, 4 },
333 { 7,INF, 1,INF,INF,INF},
334 { INF, 5, 5, 4,INF,INF},
335 };
336
337 Graph *G = createGraph(v, src, 6);
338 // prime(G, src);
339 // Kruskal(src, 6);
340 // show(G);
341 // BFS(G);
342 // DFS(G);
343 // cout<<"**********************"<<endl;
344 // DFS(G, 0);
345 flyoed(src,5, 4);
346 cout<<endl;
347 Dijkstra(src, 5, 4);
348 }