|
|
#define _CRT_SECURE_NO_WARNINGS
|
|
|
#include <stdio.h>
|
|
|
#include <stdlib.h>
|
|
|
#include <limits.h>
|
|
|
|
|
|
/* O(n^2), n - количество вершин, используем матрицу смежности */
|
|
|
|
|
|
void solve(int **adj, int **res, int n);
|
|
|
|
|
|
int main() {
|
|
|
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 **res = (int**)calloc(n, sizeof(int*));
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
res[i] = (int*)calloc(n, sizeof(int));
|
|
|
}
|
|
|
|
|
|
solve(adj, res, n);
|
|
|
|
|
|
printf("Решение:\n");
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
for (int j = i + 1; j < n; j++) {
|
|
|
if (res[i][j] != 0) {
|
|
|
printf("%i-%i: %i\n", i, j, res[i][j]);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/* Освобождаем память */
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
free(adj[i]);
|
|
|
}
|
|
|
free(adj);
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
free(res[i]);
|
|
|
}
|
|
|
free(res);
|
|
|
}
|
|
|
|
|
|
void solve(int **adj, int **res, int n) {
|
|
|
/* Множество выбранных вершин, 1 - выбрано, 0 - не выбрано */
|
|
|
int* set = (int *)calloc(n, sizeof(int));
|
|
|
/* Выбрали первую вершину */
|
|
|
set[0] = 1;
|
|
|
/* Количество выбранных вершин */
|
|
|
int set_size = 1;
|
|
|
while (set_size != n) {
|
|
|
/* "Бесконечность" */
|
|
|
int min = INT_MAX;
|
|
|
/* Номер вершины */
|
|
|
int k_i;
|
|
|
int k_j;
|
|
|
for (int i = 0; i < n; i++) {
|
|
|
/* Если вершина еще не выбрана, то пропускаем её */
|
|
|
if (!set[i]) {
|
|
|
continue;
|
|
|
}
|
|
|
/* Рассматриваем выбранные вешины */
|
|
|
for (int j = 0; j < n; j++) {
|
|
|
/* Если вершина k_j выбрана, то пропускаем её, она уже в компоненте связности */
|
|
|
if (set[j] == 1) {
|
|
|
continue;
|
|
|
}
|
|
|
/* Выбираем кратчайшее ребро */
|
|
|
if (min > adj[i][j] && adj[i][j]) {
|
|
|
min = adj[i][j];
|
|
|
k_i = i;
|
|
|
k_j = j;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
/* Добавляем вершину k_j в компоненту связности */
|
|
|
set[k_j] = 1;
|
|
|
/* Сохраняем в симметрическую матрицу результат */
|
|
|
res[k_i][k_j] = adj[k_i][k_j];
|
|
|
res[k_j][k_i] = adj[k_i][k_j];
|
|
|
set_size++;
|
|
|
}
|
|
|
free(set);
|
|
|
}
|