Advertisement
karbaev

Ford-Bellman AdL

Mar 28th, 2016
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.13 KB | None | 0 0
  1. struct edge {
  2.     int a, b, cost;
  3. };
  4.  
  5. int n, m, v;
  6. vector<edge> e;
  7. const int INF = 1000000000;
  8.  
  9. void solve() {
  10.     vector<int> d (n, INF);
  11.     d[v] = 0;
  12.     for (int i=0; i<n-1; ++i)
  13.         for (int j=0; j<m; ++j)
  14.             if (d[e[j].a] < INF)
  15.                 d[e[j].b] = min (d[e[j].b], d[e[j].a] + e[j].cost);
  16.     // вывод d, например, на экран
  17. }
  18.  
  19.  
  20. //Этот алгоритм можно несколько ускорить: зачастую ответ находится уже за несколько фаз,
  21. //а оставшиеся фазы никакой полезной работы не происходит, лишь впустую просматриваются все рёбра.
  22. //Поэтому будем хранить флаг того, изменилось что-то на текущей фазе или нет,
  23. //и если на какой-то фазе ничего не произошло, то алгоритм можно останавливать.
  24. //(Эта оптимизация не улучшает асимптотику, т.е. на некоторых графах по-прежнему будут нужны все n-1 фаза,
  25. //но значительно ускоряет поведение алгоритма "в среднем", т.е. на случайных графах.)
  26.  
  27. //С такой оптимизацией становится вообще ненужным ограничивать вручную число фаз алгоритма числом n-1 —
  28. //он сам остановится через нужное число фаз.
  29.  
  30. void solve() {
  31.     vector<int> d (n, INF);
  32.     d[v] = 0;
  33.     for (;;) {
  34.         bool any = false;
  35.         for (int j=0; j<m; ++j)
  36.             if (d[e[j].a] < INF)
  37.                 if (d[e[j].b] > d[e[j].a] + e[j].cost) {
  38.                     d[e[j].b] = d[e[j].a] + e[j].cost;
  39.                     any = true;
  40.                 }
  41.         if (!any)  break;
  42.     }
  43.     // вывод d, например, на экран
  44. }
  45.  
  46.  
  47. //Приведём реализацию Форда-Беллмана с восстановлением пути до какой-то заданной вершины t:
  48.  
  49. void solve() {
  50.     vector<int> d (n, INF);
  51.     d[v] = 0;
  52.     vector<int> p (n, -1);
  53.     for (;;) {
  54.         bool any = false;
  55.         for (int j=0; j<m; ++j)
  56.             if (d[e[j].a] < INF)
  57.                 if (d[e[j].b] > d[e[j].a] + e[j].cost) {
  58.                     d[e[j].b] = d[e[j].a] + e[j].cost;
  59.                     p[e[j].b] = e[j].a;
  60.                     any = true;
  61.                 }
  62.         if (!any)  break;
  63.     }
  64.  
  65.     if (d[t] == INF)
  66.         cout << "No path from " << v << " to " << t << ".";
  67.     else {
  68.         vector<int> path;
  69.         for (int cur=t; cur!=-1; cur=p[cur])
  70.             path.push_back (cur);
  71.         reverse (path.begin(), path.end());
  72.  
  73.         cout << "Path from " << v << " to " << t << ": ";
  74.         for (size_t i=0; i<path.size(); ++i)
  75.             cout << path[i] << ' ';
  76.     }
  77. }
  78. //Здесь мы сначала проходимся по предкам, начиная с вершины t, и сохраняем весь пройденный путь в списке  path.
  79. //В этом списке получается кратчайший путь от v до t, но в обратном порядке,
  80. //поэтому мы вызываем reverse от него и затем выводим.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement