最小生成树
1 #include<stdio.h> 2 #include "iostream" 3 #include "stdlib.h" 4 5 #define MAXVERTEX 20 6 7 typedef struct { 8 char vexs[MAXVERTEX];//顶点向量 9 int arcs[MAXVERTEX][MAXVERTEX];//邻接矩阵 10 int vexnum, arcnum;//(无向)图当前顶点数和弧数 11 }Graph; 12 13 typedef struct { 14 char v, w; 15 int edge; 16 }Treever; 17 18 19 20 //创建图,读取:顶点数,顶点向量,邻接矩阵;-1代表无穷大;0是自环,不考虑 21 void creatGraph(Graph &G) { 22 scanf_s("%d\n", &G.vexnum); 23 for (int i = 0; i < G.vexnum; i++) { 24 scanf_s("%c", &G.vexs[i]); 25 } 26 int a = 0; 27 for (int i = 0; i < G.vexnum; i++) 28 { 29 for (int j = 0; j < G.vexnum; j++) { 30 scanf_s("%d", &G.arcs[i][j]); 31 if (G.arcs[i][j] > 0) 32 a++; 33 if (G.arcs[i][j] == -1) 34 G.arcs[i][j] = INT_MAX; 35 } 36 } 37 G.arcnum = a / 2; 38 } 39 40 void Prim(Graph & G, Treever MinTREE[]) { 41 int flag[MAXVERTEX] = { 0 }; 42 int i, j, mincost = INT_MAX, key1=0,key2 = 0; 43 for (i = 1; i < G.vexnum; i++) {//n个顶点,则有n-1个边,即n-1个Treever 44 MinTREE[i].v = G.vexs[i]; 45 MinTREE[i].edge = INT_MAX; 46 } 47 48 for (i = 1; i < G.vexnum; i++) {//i用来记录进行了n-1次循环 49 mincost = INT_MAX; 50 for (j = 1; j < G.vexnum; j++) {//比较矩阵key1行每个弧长与Tree对应的,改为小值 51 if (G.arcs[key1][j] < MinTREE[j].edge&&flag[j] != 1) 52 { 53 MinTREE[j].edge = G.arcs[key1][j];//改变弧长时同时改变对应的邻接点 54 MinTREE[j].w = G.vexs[key1]; 55 } 56 if (MinTREE[j].edge < mincost&&flag[j] != 1) 57 { 58 mincost = MinTREE[j].edge;//记录最短弧长 59 key2 = j; 60 } 61 } 62 flag[key2] = 1; 63 key1 = key2; 64 } 65 66 } 67 //从小到大 68 void sortlist1(Graph & G, Treever list[]) {//构建排序邻接表(不重复,去掉对称),从小到大 69 int i, j, a = 1; 70 for (i = 0; i < G.vexnum; i++) { 71 for (j = i + 1; j < G.vexnum; j++) { 72 if (G.arcs[i][j] != INT_MAX) { 73 list[a].edge = G.arcs[i][j]; 74 list[a].v = G.vexs[i]; 75 list[a].w = G.vexs[j]; 76 a++; 77 } 78 } 79 } 80 //选择排序 81 int min,mini=21; 82 Treever temp; 83 for (j = 1; j <= G.arcnum; j++)//list数组元素个数等于弧数 84 { 85 min = list[j].edge; 86 mini = j; 87 for (i = j+1; i <= G.arcnum; i++) 88 { 89 if (list[i].edge < min) { 90 min = list[i].edge; 91 mini = i; 92 } 93 } 94 if (mini != j) { 95 temp = list[mini]; 96 list[mini] = list[j]; 97 list[j] = temp; 98 } 99 } 100 } 101 102 int index(char h) { 103 int a = 0; 104 if (h >= '0'&&h <= '9') 105 a = h - '0'; 106 else if (h >= 'a'&&h <= 'z') 107 { 108 a = h - 'a'; 109 } 110 else 111 { 112 if (h >= 'A'&&h <= 'Z') 113 a = h - 'A'; 114 } 115 return a; 116 } 117 int findroot(int root[], char l) {//不能只通过判断两点是否在同一集合上,来判断是否有回路;需要找根,根相同说明两点连上有回路 118 int a = index(l); 119 while (root[a] != -1) 120 a = root[a]; 121 return a; 122 } 123 124 void Kruskal(Graph & G, Treever MinTREE[]) { 125 Treever list[MAXVERTEX]; 126 sortlist1(G, list); 127 int root[MAXVERTEX],i,j,p1,p2,k=1; 128 for (i = 0; i < G.vexnum; i++) 129 root[i] = -1; 130 for (i = 1; i <= G.arcnum; i++) { 131 p1 = findroot(root, list[i].v); 132 p2 = findroot(root, list[i].w); 133 if (p1 != p2) 134 { 135 MinTREE[k] = list[i]; 136 root[index(list[i].w)] = index(list[i].v); 137 k++; 138 } 139 } 140 } 141 142 int FirstAdj(Graph &G, int v) { 143 int i; 144 for (i = 0; i < G.vexnum; i++) { 145 if (G.arcs[v][i] < INT_MAX&&G.arcs[v][i] != 0) 146 return i; 147 } 148 return -1; 149 } 150 151 int NextAdj(Graph &G, int v, int w) { 152 int i; 153 for (i = w+1; i < G.vexnum; i++) { 154 if (G.arcs[v][i] < INT_MAX&&G.arcs[v][i] != 0) 155 return i; 156 } 157 return -1; 158 } 159 160 void DFS(Graph &G, int v,int visited[]) { 161 visited[v] = 1; 162 for (int w = FirstAdj(G, v); w >= 0; w = NextAdj(G, v, w)) 163 if (!visited[w]) 164 DFS(G, w, visited); 165 } 166 167 int connect(Graph&G) {//若连通,只从顶点0开始深度搜索,即可遍历全部顶点 168 int visited[MAXVERTEX] = { 0 }; 169 DFS(G, 0, visited); 170 for (int i = 0; i < G.vexnum; i++) { 171 if (visited[i] == 0) 172 return 0; 173 } 174 return 1; 175 } 176 //从大到小 177 void sortlist2(Graph & G, Treever list[]) {//构建排序邻接表(不重复,去掉对称),从大到小 178 int i, j, a = 1; 179 for (i = 0; i < G.vexnum; i++) { 180 for (j = i + 1; j < G.vexnum; j++) { 181 if (G.arcs[i][j] != INT_MAX) { 182 list[a].edge = G.arcs[i][j]; 183 list[a].v = G.vexs[i]; 184 list[a].w = G.vexs[j]; 185 a++; 186 } 187 } 188 } 189 //选择排序 190 int max,maxi = 21; 191 Treever temp; 192 for (j = 1; j <= G.arcnum; j++)//list数组元素个数等于弧数 193 { 194 max = list[j].edge; 195 maxi = j; 196 for (i = j + 1; i <= G.arcnum; i++) 197 { 198 if (list[i].edge > max) { 199 max = list[i].edge; 200 maxi = i; 201 } 202 } 203 if (maxi != j) { 204 temp = list[maxi]; 205 list[maxi] = list[j]; 206 list[j] = temp; 207 } 208 } 209 } 210 211 212 //去边法 213 void De_edge(Graph & G, Treever MinTREE[]) { 214 Treever list[MAXVERTEX]; 215 sortlist2(G, list); 216 int key,a=1,ard=G.arcnum; 217 for (int i = 1; i <= ard; i++) { 218 key = G.arcs[index(list[i].v)][index(list[i].w)]; 219 G.arcs[index(list[i].v)][index(list[i].w)] = G.arcs[index(list[i].w)][index(list[i].v)] = INT_MAX; 220 G.arcnum--; 221 if (!connect(G)) { 222 G.arcs[index(list[i].v)][index(list[i].w)] = G.arcs[index(list[i].w)][index(list[i].v)] = key; 223 G.arcnum++; 224 MinTREE[a] = list[i]; 225 a++; 226 } 227 } 228 229 } 230 231 void print(Graph & G, Treever MinTREE[]) { 232 for (int i = 1; i < G.vexnum; i++) 233 printf("%c ,%d ,%c\n", MinTREE[i].v, MinTREE[i].edge, MinTREE[i].w); 234 } 235 236 int main() { 237 Graph G; 238 Treever MinTREE[MAXVERTEX]; 239 creatGraph(G); 240 printf("Prim算法:\n"); 241 Prim(G, MinTREE); 242 print(G, MinTREE); 243 printf("Kruskal算法:\n"); 244 Kruskal(G, MinTREE); 245 print(G, MinTREE); 246 printf("去边法:\n"); 247 De_edge(G, MinTREE); 248 print(G, MinTREE); 249 system("PAUSE"); 250 }