моя контактная информация
Почтамезофия@protonmail.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Оглавление
Алгоритм Флойда, полное название алгоритма Флойда-Уоршалла, представляет собой алгоритм динамического программирования, используемый для решения задачи о кратчайшем пути между всеми парами вершин графа. Он подходит для взвешенных ориентированных графов и может обрабатывать ребра с отрицательным весом (но не графы, содержащие циклы с отрицательным весом), а также может определять, есть ли в графе циклы с отрицательным весом.
Основная идея алгоритма Флойда — динамическое программирование, а его основные этапы заключаются в следующем:
Реализация алгоритма Флойда обычно использует тройной цикл. Внешний цикл обходит все промежуточные вершины k, а два внутренних цикла обходят все пары вершин (i, j), чтобы проверить, существует ли более короткий путь.
Предположим, у нас есть взвешенный граф G, содержащий n вершин, мы можем использовать двумерный массивdist[][]
для хранения кратчайшей длины пути между каждой парой вершин. Изначально,dist[i][j]
устанавливается как вес непосредственно связанного ребра в графе. Если между i и j нет непосредственно связанного ребра, то.dist[i][j]
Установлено на бесконечность (означает недостижимость).
инициализация : Создайте матрицу D размера n×n, где D[i][j] инициализируется весом прямого ребра от i до j в графе или устанавливается равным бесконечности, если между i и j нет прямого ребра. Диагональный элемент D[i][i] = 0.
динамическое программирование : Для каждой вершины k (как промежуточной вершины) обновить кратчайший путь между каждой парой вершин i и j. Можно получить более короткий путь с k в качестве промежуточной точки. Формула обновления: D[i][j] = min(D[i][j], D[i][k] + D[k][j]). Это означает, что если путь от i до j становится короче через k в качестве промежуточной вершины, обновите D[i][j].
Вывод результата: После n раундов итераций каждый элемент D[i][j] в матрице D представляет собой кратчайший путь от i до j.
343. Сортировка - Банк вопросов AcWing
- #include <algorithm>
- #include <bits/stdc++.h>
- #include <iostream>
- using namespace std;
-
- #define PII pair<int, int>
- #define fi first
- #define se second
- #define endl 'n'
- map<int, int> mp;
-
- const int N = 210, mod = 1e9 + 7;
- int T, n, m, k;
- int a[N], dist[N][N];
- PII ans[N];
-
- void floyd(int x) // 以 x 为中转点,更新其他点。
- {
- for (int i = 1; i <= n; i++)
- for (int j = 1; j <= n; j++)
- dist[i][j] = min(dist[i][j], dist[i][x] + dist[x][j]);
- }
-
- bool pd() // 判断是否所有点都已确定
- {
- for (int i = 1; i <= n; i++) {
- int cnt = 0;
- for (int j = 1; j <= n; j++)
- if (dist[i][j] != 1e9)
- cnt++; // 当前点能到达的点数
- ans[i] = {cnt, i};
- for (int j = 1; j <= n; j++)
- if (i != j && dist[j][i] != 1e9)
- cnt++; // 能到达当前点的点数
- if (cnt != n)
- return 0;
- }
- sort(ans + 1, ans + n + 1);
- return 1;
- }
-
- int main() {
- while (cin >> n >> m && n) {
- for (int i = 1; i <= n; i++)
- for (int j = 1; j <= n; j++)
- if (i != j)
- dist[i][j] = 1e9;
-
- int flag = 0;
- for (int i = 1; i <= m; i++) {
- char a, t, b;
- cin >> a >> t >> b;
- int x = a - 'A' + 1, y = b - 'A' + 1; // 现在要加一条从 y 到 x 的边
-
- if (!flag && dist[x][y] != 1e9) // 发现已经从x能到y,出现矛盾
- {
- printf("Inconsistency found after %d relations.n", i);
- flag = 1;
- }
-
- dist[y][x] = 1;
- floyd(x), floyd(y); // 分别以 x 和 y 为中转点更新其他点
- if (!flag && pd()) { // 发现所有点都已确定
- printf("Sorted sequence determined after %d relations: ", i);
- for (int i = 1; i <= n; i++)
- cout << char(ans[i].se + 'A' - 1);
- printf(".n");
- flag = 1;
- }
- }
- if (!flag)
- printf("Sorted sequence cannot be determined.n"); // 无法确定
- }
-
- return 0;
- }
dist
Двумерный массив инициализируется бесконечностью, а это означает, что по умолчанию между неравенствами нет определенного отношения порядка.dist
Матрица, использующая алгоритм Флойда для обновления кратчайшего пути между всеми неравенствами, фактически обновляет отношения «приоритета» или «порядка».