monyca98

algoritmul lui johnson

May 24th, 2018
48
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.87 KB | None | 0 0
  1. #include<iostream>
  2. #include<fstream>
  3. #include<vector>
  4. #include<queue>
  5. #include<algorithm>
  6. #include<functional>
  7. #define MAX_SIZE 3000
  8. #define INF 999
  9.  
  10. typedef std::vector<int> vector;
  11. typedef std::pair<int, int> p;
  12. vector vis;
  13. vector g[MAX_SIZE];   //the graph stored in an adjacency matrix
  14. int  n, m;    //n- no of vertices, m -no of edges
  15. std::vector<std::pair<int, int>> dist;  //first to store the distance
  16.                                         //second to store the parent
  17. int source;
  18. void read()
  19. {
  20.     std::ifstream in("file.txt");
  21.     if (!in.is_open())
  22.         std::cout << "Unable to open the file!\n";
  23.     else
  24.     {
  25.         int x, y, w;
  26.         in >> n >> m;
  27.         in >> source;
  28.         for (long long int i = 0; i < n; i++)
  29.             g[i].assign(n, -1);
  30.  
  31.         for (long long int i = 0; i < m; i++)
  32.         {
  33.             in >> x >> y >> w;
  34.             g[x][y] = w;
  35.         }
  36.     }
  37. }
  38. void init_dist()
  39. {
  40.     for (int i = 0; i <= n; i++)
  41.     {
  42.         dist.push_back({ INF,-1 });
  43.         //here NIL parent is -1
  44.     }
  45. }
  46. bool belman_ford(int source)
  47. {
  48.     int traverse;
  49.     init_dist();
  50.     dist[source] = { 0,-1 };
  51.     for (int i = 1; i<n; i++)
  52.         for (int j = 1; j <n; j++)
  53.         {
  54.             traverse = 1;
  55.             while (traverse <n)
  56.             {
  57.                 if (dist[j].first != INF)
  58.                 {
  59.                     //checking for relaxation
  60.                     if (g[j][traverse] != -1 && dist[traverse].first > dist[j].first + g[j][traverse])
  61.                     {
  62.                         dist[traverse].first = dist[j].first + g[j][traverse];
  63.                         dist[traverse].second = j;
  64.                     }
  65.                 }
  66.                 ++traverse;
  67.             }
  68.         }
  69.     //checking for negative cicles
  70.     for (int i = 1; i <n; i++)
  71.     {
  72.         traverse = 1;
  73.         while (traverse <n)
  74.         {
  75.             if (g[i][traverse] != -1 && dist[i].first + g[i][traverse] < dist[traverse].first)
  76.             {
  77.                 return false;
  78.             }
  79.             ++traverse;
  80.         }
  81.     }
  82.     return true;
  83. }
  84. void change_matrix()
  85. {
  86.  
  87.     vector g_[MAX_SIZE];
  88.     for (int i = 0; i <= n + 1; i++)
  89.         g_[i].assign(n + 1, 0);
  90.     //create the g_ graph which includes the source
  91.     //change the iteration to put the source on the 0 position
  92.     for (int i = 0; i <= n; i++)
  93.     {
  94.         g_[0][i] = 0;
  95.         g_[i][0] = 0;
  96.         //here 0 will be -1
  97.     }
  98.     for (int i = 0; i<n; i++)
  99.         for (int j = 0; j<n; j++)
  100.             g_[i + 1][j + 1] = g[i][j];
  101.     g->resize(n + 1);
  102.     for (int i = 0; i <= n; i++)
  103.         g[i].resize(n + 1);
  104.     for (int i = 0; i <= n; i++)
  105.         for (int j = 0; j <= n; j++)
  106.             g[i][j] = g_[i][j];
  107. }
  108. void dijkstra(int source)
  109. {
  110.     std::priority_queue<p, std::vector<p>, std::greater<p>> Q;
  111.     dist[source].first = 0;
  112.     Q.push({ 0,source });
  113.     while (!Q.empty())
  114.     {
  115.         int a = Q.top().second;
  116.         Q.pop();
  117.         for (int j = 1; j <n; j++)
  118.         {
  119.             if (g[a][j] != -1 && dist[j].first > dist[a].first + g[a][j])
  120.             {
  121.                 dist[j].first = dist[a].first + g[a][j];
  122.                 Q.push({ dist[j].first,j });
  123.             }
  124.         }
  125.  
  126.  
  127.     }
  128. }
  129. void johnson(int source)
  130. {
  131.     /*std::cout << "before adding source\n";
  132.     for (int i = 0; i<n; i++)
  133.     {
  134.         for (int j = 0; j<n; j++)
  135.             std::cout << g[i][j] << " ";
  136.         std::cout << std::endl;
  137.     }*/
  138.     change_matrix();
  139.     /*std::cout << "after adding source\n";
  140.     for (int i = 0; i <= n; i++)
  141.     {
  142.         for (int j = 0; j <= n; j++)
  143.             std::cout << g[i][j] << " ";
  144.         std::cout << std::endl;
  145.     }*/
  146.     n += 1;
  147.     if (belman_ford(source))
  148.     {
  149.  
  150.         for (int k = 0; k<n; k++)
  151.             std::cout << dist[k].first << " " << dist[k].second << ";";
  152.         for (int i = 1; i < n; i++)
  153.             for (int j = 1; j <n; j++)
  154.                 //if (g[i][j] == 0)
  155.                 g[i][j] += dist[i].first - dist[j].first;
  156.  
  157.         std::cout << "after belman_ford:\n";
  158.         for (int i = 0; i<n; i++)
  159.         {
  160.             for (int j = 0; j<n; j++)
  161.                 std::cout << g[i][j] << " ";
  162.             std::cout << std::endl;
  163.         }
  164.         init_dist();
  165.         dist[source].first = 0;
  166.         dijkstra(source);
  167.     }
  168.     else
  169.         std::cout << "The graph contains negative cicles!\n";
  170. }
  171. int main()
  172. {
  173.     read();
  174.     johnson(source);
  175.     std::cout << "The minimum distances from " << source << " to every following nodes are:\n";
  176.     for (int i = 1; i <n; i++)
  177.         std::cout << "node:" << i << " distance:" << dist[i].first << " parent:" << dist[i].second << "\n";
  178.  
  179.     return 0;
  180. }
Add Comment
Please, Sign In to add comment