Advertisement
mrlantan

Untitled

Nov 21st, 2020
868
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.93 KB | None | 0 0
  1. #include <chrono>
  2. #include <iostream>
  3. #include <sstream>
  4. #include <vector>
  5. #include <random>
  6. #include <set>
  7. #include <unordered_set>
  8.  
  9. std::vector<std::vector<int>> g;
  10.  
  11. std::pair<std::vector<int>, bool> TryFindColoring(const std::vector<int>& colors,
  12.                                  const std::vector<std::unordered_set<int>>& possible_colors,
  13.                                  const std::set<std::pair<int, int>>& possible_colors_sizes) {
  14.  
  15.     if (possible_colors_sizes.empty()) {
  16.         return { colors, true };
  17.     }
  18.  
  19.     if (possible_colors_sizes.begin()->first == 0) {
  20.         return { {}, false };
  21.     }
  22.  
  23.     auto new_colors = colors;
  24.     auto best_index = possible_colors_sizes.begin()->second;
  25.  
  26.     for (auto possible_color : possible_colors[best_index]) {
  27.         new_colors[best_index] = possible_color;
  28.         auto new_possible_colors = possible_colors;
  29.         auto new_possible_colors_sizes = possible_colors_sizes;
  30.  
  31.         new_possible_colors[best_index].clear();
  32.         new_possible_colors_sizes.erase(new_possible_colors_sizes.begin());
  33.  
  34.         for (auto to : g[best_index]) {
  35.             auto it = new_possible_colors[to].find(possible_color);
  36.             if (it != new_possible_colors[to].end()) {
  37.                 new_possible_colors_sizes.erase({new_possible_colors[to].size(), to});
  38.                 new_possible_colors[to].erase(it);
  39.                 new_possible_colors_sizes.insert({new_possible_colors[to].size(), to});
  40.             }
  41.         }
  42.  
  43.         auto result = TryFindColoring(new_colors, new_possible_colors, new_possible_colors_sizes);
  44.         if (result.second) {
  45.             return result;
  46.         }
  47.  
  48.         new_colors[best_index] = 0;
  49.     }
  50.  
  51.     return {{}, false};
  52. }
  53.  
  54. auto GeneratePossibleColors(const std::vector<int>& colors, int max_color) {
  55.     std::vector<std::unordered_set<int> > possible_colors(colors.size());
  56.     std::set<std::pair<int, int>> possible_colors_sizes;
  57.  
  58.     for (int i = 0; i < colors.size(); ++i) {
  59.         if (colors[i] == 0) {
  60.             for (int j = 1; j <= max_color; ++j) {
  61.                 possible_colors[i].insert(j);
  62.             }
  63.  
  64.             for (auto to : g[i]) {
  65.                 if (colors[to] != 0) {
  66.                     possible_colors[i].erase(colors[to]);
  67.                 }
  68.             }
  69.  
  70.             possible_colors_sizes.insert({possible_colors[i].size(), i});
  71.         }
  72.     }
  73.  
  74.     return std::make_pair(possible_colors, possible_colors_sizes);
  75. }
  76.  
  77. void Solve(std::istream& is, std::ostream& os) {
  78.     int n, m;
  79.     is >> n >> m;
  80.  
  81.     g.resize(n);
  82.     std::vector<int> colors(n);
  83.     std::vector<std::set<int>> possible_colors(n);
  84.  
  85.     for (int i = 0; i < m; ++i) {
  86.         int x, y;
  87.         is >> x >> y;
  88.         x--, y--;
  89.         g[x].push_back(y);
  90.         g[y].push_back(x);
  91.     }
  92.  
  93.     int max_color = 0;
  94.  
  95.     for (int i = 0; i < n; ++i) {
  96.         is >> colors[i];
  97.         max_color = std::max(max_color, colors[i]);
  98.     }
  99.  
  100.     int l = max_color - 1;
  101.     int r = n + 1;
  102.  
  103.     auto min_number_colors = n + 1;
  104.     std::vector<int> min_coloring = {};
  105.  
  106.     while(r - l > 1) {
  107.         int m = (r + l) / 2;
  108.         std::cout << "Testing " << m << std::endl;
  109.         auto possible_colors_data = GeneratePossibleColors(colors, m);
  110.         auto result = TryFindColoring(colors, possible_colors_data.first, possible_colors_data.second);
  111.  
  112.         if (result.second) {
  113.             if (m < min_number_colors) {
  114.                 min_number_colors = m;
  115.                 min_coloring = result.first;
  116.             }
  117.             r = m;
  118.         } else {
  119.             l = m;
  120.         }
  121.     }
  122.  
  123.     os << min_number_colors - max_color << std::endl;
  124.     for (auto color : min_coloring) {
  125.         os << color << " ";
  126.     }
  127.     os << std::endl;
  128. }
  129.  
  130. template <typename Generator>
  131. std::vector<std::pair<int, int>> GenerateRandomGraph(int vertices, int edges, Generator& gen) {
  132.     std::vector<std::pair<int, int>> result;
  133.     g.resize(vertices);
  134.     int added_edges = 0;
  135.  
  136.     std::vector<std::pair<int, int>> edges_vec;
  137.     for (int i = 0; i < vertices; ++i) {
  138.         for (int j = i + 1; j < vertices; ++j) {
  139.             edges_vec.emplace_back(i, j);
  140.         }
  141.     }
  142.  
  143.     int prev_size = edges_vec.size();
  144.  
  145.     std::uniform_int_distribution<int> distribution(0, prev_size - 1);
  146.  
  147.     while(result.size() < edges) {
  148.         if (added_edges >= prev_size / 2) {
  149.             std::vector<std::pair<int, int>> new_edges_vec;
  150.             for (int i = 0; i < edges_vec.size(); ++i) {
  151.                 if (edges_vec[i] != std::pair{-1, -1}) {
  152.                     new_edges_vec.push_back(std::move(edges_vec[i]));
  153.                 }
  154.             }
  155.  
  156.             edges_vec = std::move(new_edges_vec);
  157.             added_edges -= prev_size;
  158.             prev_size = edges_vec.size();
  159.         }
  160.  
  161.         int index = distribution(gen);
  162.         if (edges_vec[index] == std::pair{-1, -1}) {
  163.             continue;
  164.         } else {
  165.             result.push_back(edges_vec[index]);
  166.             edges_vec[index] = {-1, -1};
  167.             ++added_edges;
  168.         }
  169.     }
  170.  
  171.     return result;
  172. }
  173.  
  174. int main() {
  175.     std::ios_base::sync_with_stdio(false);
  176.     std::cin.tie(nullptr);
  177.     std::mt19937 gen(92423512);
  178.  
  179.     std::stringstream ss;
  180.  
  181.     int vertices = 10;
  182.     int edges_num = 25;
  183.  
  184.     auto edges = GenerateRandomGraph(vertices, edges_num, gen);
  185.     ss << vertices << " " << edges_num << "\n";
  186.     for (auto& edge : edges) {
  187.         ss << edge.first + 1 << " " << edge.second + 1 << "\n";
  188.     }
  189.  
  190.     for (int i = 0; i < edges.size(); ++i) {
  191.         ss << "0 ";
  192.     }
  193.     ss << "\n";
  194.  
  195.     auto start_time = std::chrono::high_resolution_clock::now();
  196.     Solve(ss, std::cout);
  197.     auto finish_time = std::chrono::high_resolution_clock::now();
  198.  
  199.     std::cout << vertices << " vertices " << edges_num << " edges " <<
  200.         std::to_string(duration_cast<std::chrono::milliseconds>(finish_time - start_time).count()) << " milliseconds\n";
  201.  
  202.     return 0;
  203. }
  204.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement