1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdbool.h>
5
6 #define MaxVertexNodeNumSize 1000
7 #define MaxVertexNodeNameSize 100
8
9 struct VertexBodyNode
10 {
11 char VertexName[MaxVertexNodeNameSize];
12 int ArcWeight;
13 int VertexIndex;
14 struct VertexBodyNode *Next;
15 };
16
17 struct VertexHeadNode
18 {
19 char VertexName[MaxVertexNodeNameSize];
20 int VertexWeight;
21 struct VertexBodyNode *Next;
22 };
23
24 struct _Graph
25 {
26 struct VertexHeadNode VertexHeadNodeList[MaxVertexNodeNumSize];
27 int ArcNum,VertexNum;
28 };
29
30 int VertexName2Index(struct _Graph *UnsignedGraph,char *VName)
31 {
32 int i;
33 for(i = 0; i < UnsignedGraph -> VertexNum; i ++)
34 {
35 if(strcmp(UnsignedGraph -> VertexHeadNodeList[i].VertexName,VName)==0)
36 {
37 return i;
38 }
39 }
40 return -1;
41 }
42
43 void AddOneArc(struct _Graph *UnsignedGraph,int ArcIndex_1,int ArcIndex_2,int AWeight)
44 {
45 struct VertexBodyNode *BNode_1 = malloc(sizeof(struct VertexBodyNode));
46 struct VertexBodyNode *BNode_2 = malloc(sizeof(struct VertexBodyNode));
47
48 strcpy(BNode_1 -> VertexName,UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].VertexName);
49 strcpy(BNode_2 -> VertexName,UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].VertexName);
50 BNode_1 -> ArcWeight = AWeight;
51 BNode_2 -> ArcWeight = AWeight;
52 BNode_1 -> VertexIndex = ArcIndex_1;
53 BNode_2 -> VertexIndex = ArcIndex_2;
54 BNode_1 -> Next = BNode_2 -> Next = NULL;
55
56 struct VertexBodyNode *TmpPointer;
57 TmpPointer = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
58 while(TmpPointer != NULL && TmpPointer -> Next != NULL)
59 {
60 TmpPointer = TmpPointer -> Next;
61 }
62 if(TmpPointer==NULL)
63 {
64 UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next = BNode_2;
65 }
66 else
67 {
68 TmpPointer -> Next = BNode_2;
69 }
70
71 TmpPointer = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
72 while(TmpPointer != NULL && TmpPointer -> Next != NULL)
73 {
74 TmpPointer = TmpPointer -> Next;
75 }
76 if(TmpPointer==NULL)
77 {
78 UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next = BNode_1;
79 }
80 else
81 {
82 TmpPointer -> Next = BNode_1;
83 }
84 }
85
86 void DeleteOneArc(struct _Graph *UnsignedGraph,int ArcIndex_1,int ArcIndex_2)
87 {
88 struct VertexBodyNode *TmpPointer_1,*TmpPointer_2;
89
90 TmpPointer_1 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
91 TmpPointer_2 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next;
92
93 while(TmpPointer_2!=NULL && TmpPointer_2->VertexIndex!=ArcIndex_2)
94 {
95 TmpPointer_1 = TmpPointer_2;
96 TmpPointer_2 = TmpPointer_2 -> Next;
97 }
98
99 if(TmpPointer_2==NULL)
100 {
101 return ;
102 }
103 else if(TmpPointer_1 == TmpPointer_2)
104 {
105 UnsignedGraph -> VertexHeadNodeList[ArcIndex_1].Next = NULL;
106 free(TmpPointer_2);
107 }
108 else
109 {
110 TmpPointer_1 -> Next = TmpPointer_2 -> Next;
111 free(TmpPointer_2);
112 }
113
114 TmpPointer_1 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
115 TmpPointer_2 = UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next;
116
117 while(TmpPointer_2!=NULL && TmpPointer_2->VertexIndex!=ArcIndex_1)
118 {
119 TmpPointer_1 = TmpPointer_2;
120 TmpPointer_2 = TmpPointer_2 -> Next;
121 }
122
123 if(TmpPointer_2==NULL)
124 {
125 return ;
126 }
127 else if(TmpPointer_1 == TmpPointer_2)
128 {
129 UnsignedGraph -> VertexHeadNodeList[ArcIndex_2].Next = NULL;
130 free(TmpPointer_2);
131 }
132 else
133 {
134 TmpPointer_1 -> Next = TmpPointer_2 -> Next;
135 free(TmpPointer_2);
136 }
137 }
138
139 struct _Graph *UGCreat(int ArcSum,int VertexSum)
140 {
141 int i,j;
142 struct _Graph *UnsignedGraph = malloc(sizeof(struct _Graph));
143 UnsignedGraph -> ArcNum = ArcSum;
144 UnsignedGraph -> VertexNum = VertexSum;
145
146 for(i = 0; i < VertexSum; i ++)
147 {
148 scanf("%s %d",UnsignedGraph -> VertexHeadNodeList[i].VertexName,&UnsignedGraph -> VertexHeadNodeList[i].VertexWeight);
149 }
150
151 for(i = 0; i < VertexSum; i ++)
152 {
153 UnsignedGraph -> VertexHeadNodeList[i].Next = NULL;
154 }
155
156 for(i = 0; i < ArcSum; i ++)
157 {
158 char Arc_1[MaxVertexNodeNameSize];
159 char Arc_2[MaxVertexNodeNameSize];
160 int ArcIndex_1;
161 int ArcIndex_2;
162 int ArcWeight;
163
164 scanf("%s %s %d",Arc_1,Arc_2,&ArcWeight);
165
166 ArcIndex_1 = VertexName2Index(UnsignedGraph,Arc_1);
167 ArcIndex_2 = VertexName2Index(UnsignedGraph,Arc_2);
168
169 AddOneArc(UnsignedGraph,ArcIndex_1,ArcIndex_2,ArcWeight);
170 }
171 return UnsignedGraph;
172 }
173
174 void Travel(struct _Graph *UnsignedGraph)
175 {
176 char StartingPoint[MaxVertexNodeNameSize];
177 char OverPoint[MaxVertexNodeNameSize];
178
179 printf("Input start and over\n");
180 scanf("%s %s",StartingPoint,OverPoint);
181
182 int StartIndex = VertexName2Index(UnsignedGraph,StartingPoint);
183 int OverIndex = VertexName2Index(UnsignedGraph,OverPoint);
184
185 struct VertexBodyNode *TmpPointer;
186 TmpPointer = UnsignedGraph -> VertexHeadNodeList[StartIndex].Next;
187 while(TmpPointer != NULL && TmpPointer -> Next != NULL)
188 {
189 if(OverIndex==TmpPointer -> VertexIndex)
190 {
191 printf("Distance:%d GetVertexPointSum:%d",TmpPointer->ArcWeight
192 ,UnsignedGraph -> VertexHeadNodeList[StartIndex].VertexWeight+UnsignedGraph -> VertexHeadNodeList[OverIndex].VertexWeight);
193 break;
194 }
195 else
196 {
197 TmpPointer = TmpPointer -> Next;
198 }
199 }
200 }
201
202 struct UnionFindSet
203 {
204 int *ID;
205 int *Auxiliary;
206 int GroupSum;
207 int WeightOriginalTotal;
208 };
209
210 struct UnionFindSet* UnionFindSetInit(int WeightTotal)
211 {
212 struct UnionFindSet *UFSet = malloc(sizeof(struct UnionFindSet));
213
214 UFSet -> GroupSum = WeightTotal;
215 UFSet -> WeightOriginalTotal = WeightTotal;
216
217 UFSet -> ID = malloc(WeightTotal*sizeof(int));
218 UFSet -> Auxiliary = malloc(WeightTotal*sizeof(int));
219
220 int i;
221 for(i = 0; i < WeightTotal; i ++)
222 {
223 UFSet -> ID[i] = i;
224 }
225 for(i = 0; i < WeightTotal; i ++)
226 {
227 UFSet -> Auxiliary[i] = 1;
228 }
229
230 return UFSet;
231 }
232
233 int UnionFindSetFind(struct UnionFindSet* UFSet,int WeightNum)
234 {
235 if(WeightNum>UFSet -> WeightOriginalTotal-1 || WeightNum<0)
236 {
237 return -1;
238 }
239
240 while(WeightNum != UFSet -> ID[WeightNum])
241 {
242 WeightNum = UFSet -> ID[WeightNum];
243 }
244 return WeightNum;
245 }
246
247 int UnionFindSetUnion(struct UnionFindSet* UFSet,int Weight_1,int Weight_2)
248 {
249 int WeightRoot_1 = UnionFindSetFind(UFSet,Weight_1);
250 int WeightRoot_2 = UnionFindSetFind(UFSet,Weight_2);
251
252 if(WeightRoot_1 == -1 || WeightRoot_2 == -1)
253 {
254 return -1;
255 }
256 if(WeightRoot_1 == WeightRoot_2)
257 {
258 return 1;
259 }
260
261 if(UFSet -> Auxiliary[WeightRoot_1] < UFSet -> Auxiliary[WeightRoot_2])
262 {
263 UFSet -> ID[WeightRoot_1] = WeightRoot_2;
264 UFSet -> Auxiliary[WeightRoot_2] += UFSet -> Auxiliary[WeightRoot_1];
265 }
266 else
267 {
268 UFSet -> ID[WeightRoot_2] = WeightRoot_1;
269 UFSet -> Auxiliary[WeightRoot_1] += UFSet -> Auxiliary[WeightRoot_2];
270 }
271
272 UFSet -> GroupSum --;
273 return 0;
274 }
275
276 bool UnionFindSetIsConnected(struct UnionFindSet* UFSet,int Weight_1,int Weight_2)
277 {
278 return (UnionFindSetFind(UFSet,Weight_1) == UnionFindSetFind(UFSet,Weight_2));
279 }
280
281 struct KruskalElem
282 {
283 int VertexIndex_1;
284 int VertexIndex_2;
285 int ArcWeight;
286 };
287
288 int CmpStruction(const void *a,const void *b)
289 {
290 struct KruskalElem *c = (struct KruskalElem *)a;
291 struct KruskalElem *d = (struct KruskalElem *)b;
292
293 return c->ArcWeight > d->ArcWeight ? 1 : 0;
294 }
295
296 void KruskalMST(struct _Graph *UnsignedGraph)
297 {
298 struct UnionFindSet *UFSet = UnionFindSetInit(UnsignedGraph->VertexNum);
299 struct KruskalElem SortedArcList[2*UnsignedGraph->ArcNum];
300 int SortedArcListEnd = 0;
301
302 int i;
303 for(i = 0; i < UnsignedGraph->VertexNum; i ++)
304 {
305 struct VertexBodyNode *TmpPointer;
306 TmpPointer = UnsignedGraph -> VertexHeadNodeList[i].Next;
307 while(TmpPointer != NULL)
308 {
309 SortedArcList[SortedArcListEnd].VertexIndex_1 = i;
310 SortedArcList[SortedArcListEnd].VertexIndex_2 = TmpPointer -> VertexIndex;
311 SortedArcList[SortedArcListEnd++].ArcWeight = TmpPointer -> ArcWeight;
312 TmpPointer = TmpPointer -> Next;
313 }
314 }
315
316 qsort(SortedArcList,2*UnsignedGraph->ArcNum,sizeof(struct KruskalElem),CmpStruction);
317 for(i = 0;i < 2*UnsignedGraph->ArcNum;i ++)
318 {
319 if(!UnionFindSetIsConnected(UFSet,SortedArcList[i].VertexIndex_1,SortedArcList[i].VertexIndex_2))
320 {
321 printf("%s ¡ª¡ª%s Distance:%d\n",UnsignedGraph->VertexHeadNodeList[SortedArcList[i].VertexIndex_1].VertexName
322 ,UnsignedGraph->VertexHeadNodeList[SortedArcList[i].VertexIndex_2].VertexName
323 ,SortedArcList[i].ArcWeight);
324 UnionFindSetUnion(UFSet,SortedArcList[i].VertexIndex_1,SortedArcList[i].VertexIndex_2);
325 }
326 }
327 }
328
329 int main()
330 {
331 struct _Graph *G = UGCreat(8,5);
332 KruskalMST(G);
333 // Travel(G);
334 return 0;
335 }
336
337 /*
338 beijing 18
339 zhengzhou 10
340 hefei 9
341 nanjing 12
342 guangzhou 14
343 beijing zhengzhou 7
344 beijing hefei 9
345 beijing nanjing 8
346 zhengzhou hefei 5
347 hefei nanjing 3
348 zhengzhou guangzhou 7
349 hefei guangzhou 8
350 nanjing guangzhou 6
351 */