typedef struct {
int u, v, weight;
} Edge;
int parent[MAX_V];
int find(int x) {
while (parent[x] != x) x = parent[x];
return x;
}
void unite(int x, int y) {
parent[find(x)] = find(y);
}
int compareEdges(const void *a, const void *b) {
return ((Edge*)a)->weight - ((Edge*)b)->weight;
}
int* mst(int graph[MAX_V][MAX_V], int n, int *mstSize) {
Edge *edges = (Edge*)malloc(sizeof(Edge) * n * n);
int edgeCount = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (graph[i][j] > 0) {
edges[edgeCount++] = (Edge){i, j, graph[i][j]};
}
}
}
qsort(edges, edgeCount, sizeof(Edge), compareEdges);
for (int i = 0; i < n; i++) parent[i] = i;
int *mstEdges = (int*)malloc(sizeof(int) * 2 * n);
*mstSize = 0;
for (int i = 0; i < edgeCount; i++) {
int u = edges[i].u;
int v = edges[i].v;
if (find(u) != find(v)) {
unite(u, v);
mstEdges[(*mstSize)++] = u;
mstEdges[(*mstSize)++] = v;
}
}
free(edges);
return mstEdges;
}
int* preorder(int graph[MAX_V][MAX_V], int n, int start, int *orderSize) {
int *order = (int*)malloc(sizeof(int) * n);
int *stack = (int*)malloc(sizeof(int) * n);
int top = 0, visited[MAX_V] = {0};
stack[top++] = start;
*orderSize = 0;
while (top > 0) {
int u = stack[--top];
if (!visited[u]) {
visited[u] = 1;
order[(*orderSize)++] = u;
for (int v = n - 1; v >= 0; v--) {
if (graph[u][v] && !visited[v]) {
stack[top++] = v;
}
}
}
}
free(stack);
return order;
}
int tspApprox(int graph[MAX_V][MAX_V], int n) {
int mstSize;
int *mstEdges = mst(graph, n, &mstSize);
int mstGraph[MAX_V][MAX_V];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
mstGraph[i][j] = 0;
}
}
for (int i = 0; i < mstSize; i += 2) {
int u = mstEdges[i];
int v = mstEdges[i + 1];
mstGraph[u][v] = mstGraph[v][u] = 1;
}
int orderSize;
int *order = preorder(mstGraph, n, 0, &orderSize);
int totalCost = 0;
for (int i = 0; i < orderSize - 1; i++) {
totalCost += graph[order[i]][order[i + 1]];
}
totalCost += graph[order[orderSize - 1]][order[0]];
free(mstEdges);
free(order);
return totalCost;
}