fisrst algo
This commit is contained in:
parent
98b3a21582
commit
2a7e9b411d
4 changed files with 210 additions and 8 deletions
37
algo/first/Makefile
Normal file
37
algo/first/Makefile
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
CC=gcc
|
||||||
|
CFLAGS=-Wall -lm -Wall -Werror=sign-compare -Werror=array-bounds -Werror=maybe-uninitialized -Werror=unused-parameter -Werror=maybe-uninitialized -Werror=cast-qual
|
||||||
|
|
||||||
|
EXECS=application_select warshall topological dijkstra prim kruskal
|
||||||
|
|
||||||
|
build_application: application_select.c
|
||||||
|
$(CC) $(CFLAGS) application_select.c -o application_select
|
||||||
|
application_run: application_select
|
||||||
|
cat application_select.data | ./application_select
|
||||||
|
|
||||||
|
build_warshall: warshall.c
|
||||||
|
$(CC) $(CFLAGS) warshall.c -o warshall
|
||||||
|
warshall_run: warshall
|
||||||
|
cat warshall.data | ./warshall
|
||||||
|
|
||||||
|
build_topological: topological.c
|
||||||
|
$(CC) $(CFLAGS) topological.c -o topological
|
||||||
|
topological_run: topological
|
||||||
|
cat topological.data | ./topological
|
||||||
|
|
||||||
|
build_dijkstra: dijkstra.c
|
||||||
|
$(CC) $(CFLAGS) dijkstra.c -o dijkstra
|
||||||
|
dijkstra_run: dijkstra
|
||||||
|
cat dijkstra.data | ./dijkstra
|
||||||
|
|
||||||
|
build_prim: prim.c
|
||||||
|
$(CC) $(CFLAGS) prim.c -o prim
|
||||||
|
prim_run: prim
|
||||||
|
cat prim.data | ./prim
|
||||||
|
|
||||||
|
build_kruskal: kruskal.c
|
||||||
|
$(CC) $(CFLAGS) kruskal.c -o kruskal
|
||||||
|
kruskal_run: kruskal
|
||||||
|
cat kruskal.data | ./kruskal
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXECS)
|
|
@ -1,5 +1,3 @@
|
||||||
# 1
|
|
||||||
|
|
||||||
5
|
5
|
||||||
1 2
|
1 2
|
||||||
3 6
|
3 6
|
||||||
|
@ -7,9 +5,3 @@
|
||||||
5 7
|
5 7
|
||||||
1 7
|
1 7
|
||||||
|
|
||||||
# 2
|
|
||||||
|
|
||||||
3
|
|
||||||
1 5
|
|
||||||
2 3
|
|
||||||
3 4
|
|
||||||
|
|
167
algo/first/kruskal.c
Normal file
167
algo/first/kruskal.c
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
typedef struct edge {
|
||||||
|
int begin;
|
||||||
|
int end;
|
||||||
|
int len;
|
||||||
|
} Edge;
|
||||||
|
|
||||||
|
int count_edge(int **adj, int n);
|
||||||
|
Edge* create_edge_vector(int **adj, int n, int size);
|
||||||
|
void print_edges(int** adj, int n);
|
||||||
|
int** solve(Edge* vector, int size, int size_vertex);
|
||||||
|
int vector_compare(const void *a, const void *b);
|
||||||
|
void paint_vertices(Edge* vector, int size, int need_vertix, int saved_color, int *paint);
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
/* n - количество вершин, size - количество ребер */
|
||||||
|
|
||||||
|
int n;
|
||||||
|
scanf("%d", &n);
|
||||||
|
int **adj = (int**)calloc(n, sizeof(int*));
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
adj[i] = (int*)calloc(n, sizeof(int));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
for (int j = 0; j < n; j++) {
|
||||||
|
scanf("%d", &adj[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Подсчет количества ребер в исходной матрице смежности */
|
||||||
|
int size = count_edge(adj, n);
|
||||||
|
Edge *vector = create_edge_vector(adj, n, size);
|
||||||
|
/* Сортируем ребра по длине, сначала самые короткие */
|
||||||
|
qsort(vector, size, sizeof(Edge), vector_compare);
|
||||||
|
|
||||||
|
int **res = solve(vector, size, n);
|
||||||
|
print_edges(res, n);
|
||||||
|
|
||||||
|
/* Освобождаем память */
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
free(adj[i]);
|
||||||
|
}
|
||||||
|
free(adj);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
free(res[i]);
|
||||||
|
}
|
||||||
|
free(res);
|
||||||
|
free(vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
int **solve(Edge* vector, int size, int v) {
|
||||||
|
/* Результирующее остовное дерево в виде матрицы смежности */
|
||||||
|
int** res = (int**)calloc(v, sizeof(int*));
|
||||||
|
for (int i = 0; i < v; i++) {
|
||||||
|
res[i] = (int*)calloc(v, sizeof(int));
|
||||||
|
}
|
||||||
|
/* Массив с окраской каждой вершины */
|
||||||
|
int* paint = (int*)calloc(v, sizeof(int));
|
||||||
|
/* Количество рассмотренных вершин */
|
||||||
|
int n = 0;
|
||||||
|
int color = 1;
|
||||||
|
int saved_color;
|
||||||
|
/* Пока не раскрашены все вершины */
|
||||||
|
while (n != size ) {
|
||||||
|
/* Проверяем на цикл */
|
||||||
|
if ((paint[vector[n].begin] == paint[vector[n].end]) && (paint[vector[n].begin] != 0 || paint[vector[n].end] != 0)) {
|
||||||
|
n++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Создание новой компоненты связности */
|
||||||
|
if (paint[vector[n].begin] == 0 && paint[vector[n].end] == 0) {//обе вершины незакрашены
|
||||||
|
paint[vector[n].begin] = color;
|
||||||
|
paint[vector[n].end] = color;
|
||||||
|
res[vector[n].begin][vector[n].end] = vector[n].len;
|
||||||
|
/* Создаем новый цвет */
|
||||||
|
color++;
|
||||||
|
}
|
||||||
|
/* Присоединение неокрашенной вершины к существующей компоненте связности */
|
||||||
|
else if (paint[vector[n].begin] == 0) {
|
||||||
|
paint[vector[n].begin] = paint[vector[n].end];
|
||||||
|
res[vector[n].begin][vector[n].end] = vector[n].len;
|
||||||
|
}
|
||||||
|
else if (paint[vector[n].end] == 0) {
|
||||||
|
paint[vector[n].end] = paint[vector[n].begin];
|
||||||
|
res[vector[n].begin][vector[n].end] = vector[n].len;
|
||||||
|
}
|
||||||
|
/* Объединение компонент связности */
|
||||||
|
else {
|
||||||
|
/* Сохраняем цвет той компоненты, которую будем перекрашивать */
|
||||||
|
saved_color = paint[vector[n].end];
|
||||||
|
paint[vector[n].end] = paint[vector[n].begin];
|
||||||
|
res[vector[n].begin][vector[n].end] = vector[n].len;
|
||||||
|
/* Перекрашиваем вторую компоненту в цвет первой */
|
||||||
|
paint_vertices(vector, size, vector[n].end, saved_color, paint);
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(paint);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
void print_edges(int** massiv, int n) {
|
||||||
|
printf("Решение:\n");
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
for (int j = i + 1; j < n; j++) {
|
||||||
|
if (massiv[i][j] != 0) {
|
||||||
|
printf("%d-%d: %d\n", i, j, massiv[i][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Edge* create_edge_vector(int **adj, int n, int size) {
|
||||||
|
Edge* vector = (Edge*)calloc(size, sizeof(Edge));
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
for (int j = i + 1; j < n; j++) {
|
||||||
|
if (adj[i][j] != 0) {
|
||||||
|
/* Заполняем с конца */
|
||||||
|
size--;
|
||||||
|
vector[size].begin = i;
|
||||||
|
vector[size].end = j;
|
||||||
|
vector[size].len = adj[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count_edge(int **adj, int n) {
|
||||||
|
int res = 0;
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
for (int j = i + 1; j < n; j++) {
|
||||||
|
if (adj[i][j] != 0) {
|
||||||
|
res++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vector_compare(const void *a, const void *b) {
|
||||||
|
return ((const Edge *)a)->len - ((const Edge *)b)->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint_vertices(Edge* vector, int size, int need_vertix, int saved_color, int *paint) {
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
/* Если текущая ребро выходит из нужной вершины */
|
||||||
|
if (vector[i].begin == need_vertix) {
|
||||||
|
/* Если другой конец ребра - нужный по цвету (старый), то красим в цвет исходной вершины */
|
||||||
|
if (paint[vector[i].end] == saved_color) {
|
||||||
|
paint[vector[i].end] = paint[need_vertix];
|
||||||
|
/* Рекурсивно вызываем покраску для конца ребра */
|
||||||
|
paint_vertices(vector, size, vector[i].end, saved_color, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Если текущее ребро заканчивается в нужной вершине */
|
||||||
|
else if (vector[i].end == need_vertix) {
|
||||||
|
/* Аналогично случаю выше, но вызываем для начала ребра */
|
||||||
|
if (paint[vector[i].begin] == saved_color) {
|
||||||
|
paint[vector[i].begin] = paint[need_vertix];
|
||||||
|
paint_vertices(vector, size, vector[i].begin, saved_color, paint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
algo/first/kruskal.data
Normal file
6
algo/first/kruskal.data
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
5
|
||||||
|
0 9 75 0 0
|
||||||
|
9 0 95 19 42
|
||||||
|
75 95 0 51 66
|
||||||
|
0 19 51 0 31
|
||||||
|
0 42 66 31 0
|
Reference in a new issue