Advertisement
Argent007

Поиск в ширину (1) СППМиИ

Feb 22nd, 2023 (edited)
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.18 KB | None | 0 0
  1. // ConsoleApplication1.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
  2. //
  3.  
  4. #include <iostream>
  5. #include <vector>
  6. #include <algorithm>
  7. #include <queue>
  8. #include <fstream>
  9. #include <numeric>
  10.  
  11. using graph = std::vector<std::vector<int>>;
  12. using std::vector;
  13.  
  14. //базовый поиск в ширину
  15. void BFS(const graph& g, int s, vector<int>& d, vector<int>& p, bool need_init = true)
  16. {
  17.     int infty = g.size();
  18.     if (need_init)
  19.     {
  20.         d.assign(g.size(), infty);
  21.         p.assign(g.size(), -1);
  22.     }
  23.     d[s] = 0;
  24.     std::queue<int> Q;
  25.     Q.push(s);
  26.     while (Q.size())
  27.     {
  28.         auto u = Q.front();
  29.         Q.pop();
  30.         for (auto v : g[u])
  31.         {
  32.             if (d[v] == infty)
  33.             {
  34.                 d[v] = d[u] + 1;
  35.                 p[v] = u;
  36.                 Q.push(v);
  37.             }
  38.         }
  39.     }
  40. }
  41.  
  42. int count_connected_parts(const graph& g)
  43. {
  44.     int count = 0;
  45.     int infty = g.size();
  46.     vector<int> d(g.size(), infty);
  47.     vector<int> p(g.size(), -1);
  48.     for (size_t s = 0; s < g.size(); s++)
  49.     {
  50.         if (d[s] == infty)
  51.         {
  52.             BFS(g, s, d, p, false);
  53.             ++count;
  54.         }
  55.     }
  56.     return count;
  57. }
  58.  
  59. vector<int> vertices_from_shortest_path(const graph& g, int a, int b)
  60. {
  61.     int infty = g.size();
  62.     vector<int> da, db, p;
  63.     BFS(g, a, da, p, true);
  64.     BFS(g, b, db, p, true);
  65.     vector<int> res;
  66.     for (size_t u = 0; u < g.size(); u++)
  67.     {
  68.         if (da[u] + db[u] == da[b])
  69.             res.push_back(u);
  70.     }
  71.     return res;
  72. }
  73.  
  74. graph get_graph_from_stream(std::istream&& inp)
  75. {
  76.     int n;
  77.     inp >> n;
  78.     graph g(n);
  79.     int a, b;
  80.     while (inp >> a >> b)
  81.     {
  82.         g[a].push_back(b);
  83.         g[b].push_back(a);
  84.     }
  85.     return g;
  86. }
  87.  
  88. //https://pastebin.com/6MDNTGUj
  89.  
  90. bool is_tree_graph(const graph& G)
  91. {
  92.     int edge_count = std::accumulate(G.begin(), G.end(), 0,
  93.         [](auto s, const auto& list) {return s + list.size(); });
  94.     return edge_count == G.size() - 1 && count_connected_parts(G) == 1;
  95. }
  96.  
  97. vector<vector<vector<int>>> get_tree_code(const graph& T, int s)
  98. {
  99.     vector<int> d, p;
  100.     BFS(T, s, d, p, true);
  101.     int level_count = *std::max_element(begin(d), end(d)) + 1;
  102.     vector<vector<int>> levels(level_count);
  103.     for (size_t u = 0; u < T.size(); u++)
  104.         levels[d[u]].push_back(u);
  105.     vector<vector<vector<int>>> code(level_count);
  106.     vector<int> mark(T.size());
  107.     for (int lvl = level_count - 1; lvl >= 0; lvl--)
  108.     {
  109.         vector<std::pair<vector<int>, int>> level_code;
  110.         for (auto u : levels[lvl])
  111.         {
  112.             vector<int> vertex_code;
  113.             for (auto v : T[u])
  114.                 if (d[v] == lvl + 1)
  115.                     vertex_code.push_back(mark[v]);
  116.             std::sort(vertex_code.begin(), vertex_code.end());
  117.             level_code.emplace_back(std::move(vertex_code), u);
  118.         }
  119.         std::sort(level_code.begin(), level_code.end());
  120.         int cur_mark = 0;
  121.         mark[level_code[0].second] = cur_mark;
  122.         for (size_t i = 1; i < level_code.size(); i++)
  123.         {
  124.             if (level_code[i].first != level_code[i - 1].first)
  125.                 ++cur_mark;
  126.             mark[level_code[i].second] = cur_mark;
  127.         }
  128.         for (auto& [vertex_code, vertex] : level_code)
  129.             code[lvl].emplace_back(std::move(vertex_code));
  130.     }
  131.     return code;
  132. }
  133.  
  134. vector<vector<vector<int>>> get_tree_code_advanced(const graph& T, int s,
  135.     vector<vector<int>> &_levels, vector<int> &_mark)
  136. {
  137.     vector<int> d, p;
  138.     BFS(T, s, d, p, true);
  139.     int level_count = *std::max_element(begin(d), end(d)) + 1;
  140.     vector<vector<int>> levels(level_count);
  141.     for (size_t u = 0; u < T.size(); u++)
  142.         levels[d[u]].push_back(u);
  143.     vector<vector<vector<int>>> code(level_count);
  144.     vector<int> mark(T.size());
  145.     for (int lvl = level_count - 1; lvl >= 0; lvl--)
  146.     {
  147.         vector<std::pair<vector<int>, int>> level_code;
  148.         for (auto u : levels[lvl])
  149.         {
  150.             vector<int> vertex_code;
  151.             for (auto v : T[u])
  152.                 if (d[v] == lvl + 1)
  153.                     vertex_code.push_back(mark[v]);
  154.             std::sort(vertex_code.begin(), vertex_code.end());
  155.             level_code.emplace_back(std::move(vertex_code), u);
  156.         }
  157.         std::sort(level_code.begin(), level_code.end());
  158.         int cur_mark = 0;
  159.         mark[level_code[0].second] = cur_mark;
  160.         for (size_t i = 1; i < level_code.size(); i++)
  161.         {
  162.             if (level_code[i].first != level_code[i - 1].first)
  163.                 ++cur_mark;
  164.             mark[level_code[i].second] = cur_mark;
  165.         }
  166.         for (auto& [vertex_code, vertex] : level_code)
  167.             code[lvl].emplace_back(std::move(vertex_code));
  168.     }
  169.     _levels = std::move(levels);
  170.     _mark = std::move(mark);
  171.     return code;
  172. }
  173.  
  174. bool is_isomorphic_tree(const graph& T1, const graph& T2,
  175.     vector<int> &isomorphism)
  176. {
  177.     if (!is_tree_graph(T1) || !is_tree_graph(T2))
  178.         return false;
  179.     if (T1.size() != T2.size())
  180.         return false;
  181.     vector<vector<int>> levels1, levels2;
  182.     vector<int> mark1, mark2;
  183.     auto codeT1 = get_tree_code_advanced(T1, 0,levels1,mark1);
  184.     for (size_t u = 0; u < T2.size(); u++)
  185.     {
  186.         if (codeT1 == get_tree_code_advanced(T2, u, levels2, mark2))
  187.         {
  188.             isomorphism.resize(T1.size());
  189.             isomorphism[0] = u;
  190.             for (int l = 1; l < levels1.size(); l++)
  191.             {
  192.                 vector<std::pair<int, int>> t1level, t2level;
  193.                 for (auto u : levels1[l])
  194.                     t1level.push_back({ mark1[u],u });
  195.                 for (auto u : levels2[l])
  196.                     t2level.push_back({ mark2[u],u });
  197.                 std::sort(begin(t1level), end(t1level));
  198.                 std::sort(begin(t2level), end(t2level));
  199.                 for (int k = 0; k < t1level.size(); k++)
  200.                     isomorphism[t1level[k].second] = t2level[k].second;
  201.             }
  202.             return true;
  203.         }
  204.     }
  205.     return false;
  206. }
  207.  
  208. using labyrinth = vector<vector<char>>;
  209.  
  210. labyrinth get_labyrinth_from_stream(std::istream& inp)
  211. {
  212.     int row, col;
  213.     inp >> row >> col;
  214.     labyrinth lab(row, vector<char>(col));
  215.     for (size_t i = 0; i < row; i++)
  216.     {
  217.         for (size_t j = 0; j < col; j++)
  218.         {
  219.             char c;
  220.             inp >> c;
  221.             lab[row - i - 1][j] = c;
  222.         }
  223.     }
  224.     return lab;
  225. }
  226.  
  227. struct cell { int r, c; };
  228.  
  229. template <typename T>
  230. T& operator^(vector<vector<T>>& data, cell c)
  231. {
  232.     return data[c.r][c.c];
  233. }
  234.  
  235. template <typename T>
  236. T operator^(const vector<vector<T>>& data, cell c)
  237. {
  238.     return data[c.r][c.c];
  239. }
  240.  
  241. vector<cell> adjoint_cells(const labyrinth& lab, cell c)
  242. {
  243.     vector<cell> res;
  244.     for(int i=-1; i<=1; ++i)
  245.     {
  246.         if (i != 0 && i + c.r >= 0 && i + c.r < lab.size())
  247.             res.push_back({ i + c.r,c.c });
  248.         if (i != 0 && i + c.c >= 0 && i + c.c < lab[0].size())
  249.             res.push_back({ c.r,i+c.c });
  250.     }
  251.     return res;
  252. }
  253.  
  254. void BFSlab(const labyrinth& lab, cell s, vector<vector<int>>& d,
  255.     vector<vector<cell>>& p)
  256. {
  257.     int infty = lab.size() * lab[0].size();
  258.     d.assign(lab.size(), vector<int>(lab[0].size(),infty));
  259.     p.assign(lab.size(), vector<cell>(lab[0].size(), {-1,-1}));
  260.     d^s = 0;
  261.     std::queue<cell> Q;
  262.     Q.push(s);
  263.     while (Q.size())
  264.     {
  265.         auto c = Q.front();
  266.         Q.pop();
  267.         for (auto v : adjoint_cells(lab, c))
  268.         {
  269.             if ((lab^v) != '#' && (d ^ v) == infty)
  270.             {
  271.                 d^v = (d^c) + 1;
  272.                 p^v = c;
  273.                 Q.push(v);
  274.             }
  275.         }
  276.     }
  277. }
  278.  
  279.  
  280. int main()
  281. {
  282.     //auto g = get_graph_from_stream(std::ifstream("g.txt"));
  283.     //auto ab_shortest_path = vertices_from_shortest_path(g, 2, 10);
  284.     //std::cout << count_connected_parts(g) << std::endl;
  285.     //for (auto u : ab_shortest_path)
  286.     //    std::cout << u << " ";
  287.     //std::cout << std::endl;
  288.     //std::cout << "Hello World!\n";
  289.  
  290.     //auto T = get_graph_from_stream(std::ifstream("tree.txt"));
  291.     //auto code = get_tree_code(T, 1);
  292.     //for (auto& level_code : code)
  293.     //{
  294.     //    for (auto& vertex_code : level_code)
  295.     //    {
  296.     //        std::cout << "{";
  297.     //        for (int i = 0; i < vertex_code.size(); ++i)
  298.     //            std::cout << vertex_code[i] << (i < vertex_code.size() - 1 ? "," : "");
  299.     //        std::cout << "} ";
  300.     //    }
  301.     //    std::cout << std::endl;
  302.     //}
  303.     std::ifstream inp("lab.txt");
  304.     auto lab = get_labyrinth_from_stream(inp);
  305.     vector<vector<int>> d;
  306.     vector<vector<cell>> p;
  307.     BFSlab(lab, { 0,0 }, d, p);
  308.     std::cout << (d ^ cell{ 7,7 }) << std::endl;
  309. }
  310.  
  311. // Запуск программы: CTRL+F5 или меню "Отладка" > "Запуск без отладки"
  312. // Отладка программы: F5 или меню "Отладка" > "Запустить отладку"
  313.  
  314. // Советы по началу работы
  315. //   1. В окне обозревателя решений можно добавлять файлы и управлять ими.
  316. //   2. В окне Team Explorer можно подключиться к системе управления версиями.
  317. //   3. В окне "Выходные данные" можно просматривать выходные данные сборки и другие сообщения.
  318. //   4. В окне "Список ошибок" можно просматривать ошибки.
  319. //   5. Последовательно выберите пункты меню "Проект" > "Добавить новый элемент", чтобы создать файлы кода, или "Проект" > "Добавить существующий элемент", чтобы добавить в проект существующие файлы кода.
  320. //   6. Чтобы снова открыть этот проект позже, выберите пункты меню "Файл" > "Открыть" > "Проект" и выберите SLN-файл.
  321.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement