Advertisement
Guest User

Untitled

a guest
Nov 21st, 2017
69
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.39 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include "math.h"
  5. #include <limits>
  6. #include <random>
  7. #include <list>
  8. #include <queue>
  9. #include <stack>
  10. #include <random>
  11. #include <algorithm>
  12.  
  13. using std::cin;
  14. using std::cout;
  15. using std::endl;
  16. using std::vector;
  17. using std::list;
  18. using std::queue;
  19. using std::stack;
  20.  
  21.  
  22. const int BUF_LEN = 1e7;
  23. char buf[BUF_LEN];
  24. int cnt;
  25.  
  26. void * operator new(size_t len)
  27. {
  28.     void * p = (void *)(buf + cnt);
  29.     cnt += len;
  30.     return p;
  31. }
  32.  
  33. void operator delete(void * p)
  34. {
  35.    
  36. }
  37.  
  38. struct edge{
  39.     size_t a_, b_;
  40.     edge() = default;
  41.     edge(size_t a_, size_t b_) {
  42.         this->a_ = a_;
  43.         this->b_ = b_;
  44.     }
  45. };
  46. int n_;
  47. vector<edge> g1, g2;
  48. vector<size_t> degree1, degree2;
  49. vector<vector<size_t>> v_list1, v_list2;
  50. //stack<size_t> order1, order2;
  51.  
  52. void read_data() {
  53.     cin >> n_;
  54.     g1.resize(n_ - 1);
  55.     degree1.resize(n_ + 1);
  56.     v_list1.resize(n_ + 1);
  57.     for (int i = 0; i < n_ - 1; ++i) {
  58.         cin >> g1[i].a_ >> g1[i].b_;
  59.         degree1[g1[i].a_]++;
  60.         degree1[g1[i].b_]++;
  61.         v_list1[g1[i].a_].push_back(g1[i].b_);
  62.         v_list1[g1[i].b_].push_back(g1[i].a_);
  63.     }
  64.     g2.resize(n_ - 1);
  65.     degree2.resize(n_ + 1);
  66.     v_list2.resize(n_ + 1);
  67.     for (int i = 0; i < n_ - 1; ++i) {
  68.         cin >> g2[i].a_ >> g2[i].b_;
  69.         degree2[g2[i].a_]++;
  70.         degree2[g2[i].b_]++;
  71.         v_list2[g2[i].a_].push_back(g2[i].b_);
  72.         v_list2[g2[i].b_].push_back(g2[i].a_);
  73.     }
  74. }
  75.  
  76. void create_data(vector<edge> g1, vector<edge> g2) {
  77.     degree1.resize(n_ + 1);
  78.     v_list1.resize(n_ + 1);
  79.     for (int i = 0; i < n_ - 1; ++i) {
  80.         degree1[g1[i].a_]++;
  81.         degree1[g1[i].b_]++;
  82.         v_list1[g1[i].a_].push_back(g1[i].b_);
  83.         v_list1[g1[i].b_].push_back(g1[i].a_);
  84.     }
  85.     degree2.resize(n_ + 1);
  86.     v_list2.resize(n_ + 1);
  87.     for (int i = 0; i < n_ - 1; ++i) {
  88.         degree2[g2[i].a_]++;
  89.         degree2[g2[i].b_]++;
  90.         v_list2[g2[i].a_].push_back(g2[i].b_);
  91.         v_list2[g2[i].b_].push_back(g2[i].a_);
  92.     }
  93. }
  94.  
  95. struct vertex_level{
  96.     size_t vertex, level;
  97.     vertex_level() = default;
  98.     vertex_level(size_t vertex,size_t  level){
  99.         this -> vertex = vertex;
  100.         this -> level = level;
  101.     }
  102. };
  103. vector<size_t> find_center(const vector<edge>& g_, vector<size_t>& degree_,
  104.                            vector<vector<size_t>>& v_list_) {
  105.     vector<size_t> center;
  106.     queue<vertex_level> v_;
  107.     for (int i = 1; i < n_ + 1; i++) {
  108.         if (degree_[i] == 1) v_.push(vertex_level(i, 1));
  109.     }
  110.     vertex_level last;
  111.     while (v_.size() > 1) {
  112.         last = v_.front();
  113.         //order_.push(last.vertex);
  114.         v_.pop();
  115.         degree_[last.vertex]--;
  116.         for (auto j : v_list_[last.vertex]) {
  117.             if (degree_[j] > 0) {
  118.                 degree_[j]--;
  119.                 if (degree_[j] == 1) {
  120.                     v_.push(vertex_level(j, last.level + 1));
  121.                 }
  122.             }
  123.         }
  124.     }
  125.     center.push_back(v_.front().vertex);
  126.     if (last.level == v_.front().level) {
  127.         center.push_back(last.vertex);
  128.     }
  129.    
  130.     return center;
  131. }
  132.  
  133. struct node {
  134.     size_t num, hash;
  135.     vector<node*> childs;
  136.     node* parent;
  137.     ~node() {
  138.         if (childs.size() > 0) {
  139.             for (auto i : childs){
  140.                 delete i;
  141.             }
  142.         }
  143.     }
  144. };
  145. node* newNode(size_t data, node* parent)
  146. {
  147.     node* newnode = new node;
  148.     newnode->num = data;
  149.     newnode->hash = 0;
  150.     newnode->parent = parent;
  151.     //newnode->childs = default();
  152.     return newnode;
  153. }
  154.  
  155.  
  156. node* constructTreeUtil_(size_t center, vector<size_t>& degree_, vector<vector<size_t>>& v_list_, vector<bool>& col, node* parent) {
  157.    
  158.     node* root = newNode(center, parent);
  159.     degree_[center]--;
  160.     col[center] = 1;
  161.     if (degree_[center] == 0) return root;
  162.     for (auto i : v_list_[center]) {
  163.         if (degree_[i] > 0 && col[i] == 0) {
  164.             root->childs.push_back(constructTreeUtil_(i, degree_, v_list_, col, root));
  165.         }
  166.     }
  167.     return root;
  168. }
  169. node* constructTreeUtil(vector<size_t>& center, vector<size_t>& degree_,
  170.                         vector<vector<size_t>>& v_list_, node* parent) {
  171.     vector<bool> color;
  172.     color.resize(n_ + 1);
  173.     if (center.size() == 2) {
  174.         degree_[0]+= 2;
  175.         for (int i = 0; i < v_list_[center[0]].size(); ++i){
  176.             if (v_list_[center[0]][i] == center[1]) v_list_[center[0]][i] = 0;
  177.         }
  178.         for (int i = 0; i < v_list_[center[1]].size(); ++i){
  179.             if (v_list_[center[1]][i] == center[0]) v_list_[center[1]][i] = 0;
  180.         }
  181.         v_list_[0].push_back(center[0]);
  182.         v_list_[0].push_back(center[1]);
  183.         center.clear();
  184.         center.push_back(0);
  185.     }
  186.     return constructTreeUtil_(center[0], degree_, v_list_, color, parent);
  187. }
  188.  
  189.  
  190. bool compare_node_by_hash(const node* a, const node* b) {
  191.     return (a->hash > b->hash);
  192. }
  193. const int64_t prime = 196613;
  194.  
  195. size_t hash_func( size_t  key )
  196. {
  197.     key += ~(key << 32);
  198.     key ^=  (key >>  10);
  199.     key +=  (key <<  6);
  200.     key ^=  (key >> 27);
  201.     key += ~(key <<  18);
  202.     key ^=  (key >> 33);
  203.    
  204.     return key;
  205. }
  206.  
  207. int64_t hash_tree(node* root) {
  208.     int64_t hash = (hash_func(static_cast<int64_t>(root->childs.size())) % prime + 27) % prime; // какая-то функция
  209.     for (int i = 0; i < root->childs.size(); ++i) {
  210.         hash = (hash + 2 * hash_func((static_cast<int64_t>(hash_tree(root->childs[i])))) % prime) % prime; //pow(3, i)
  211.     }
  212.     hash = hash % prime;
  213.     root->hash = static_cast<size_t>(hash);
  214.     std::sort(root->parent->childs.begin(), root->parent->childs.end(), compare_node_by_hash);
  215.     return hash;
  216. }
  217.  
  218. /*int64_t hash_tree(node* root, size_t level) {
  219.     int64_t hash = (static_cast<int64_t>(root->childs.size()) % prime + 27) % prime; // какая-то функция
  220.     for (int i = 0; i < root->childs.size(); ++i) {
  221.         hash = (hash + (static_cast<int64_t>(hash_tree(root->childs[i], level +  1))
  222.                         * primes[level % primes.size()]) % prime) % prime; //pow(3, i)
  223.     }
  224.     hash = hash % prime;
  225.     root->hash = static_cast<size_t>(hash);
  226.     std::sort(root->parent->childs.begin(), root->parent->childs.end(), compare_node_by_hash);
  227.     return hash;
  228. }*/
  229.  
  230.  
  231. bool biection(node* root1, node* root2, vector<int>& ans, vector<bool>& take1, vector<bool>& take2) {
  232.     take1[root1->num] = 1;
  233.     take2[root2->num] = 1;
  234.     ans[root1->num] = static_cast<int>(root2->num);
  235.     if (root1->childs.size() != root2->childs.size()) {
  236.         return 0;
  237.     }
  238.     for (int i = 0; i < root1->childs.size(); ++i) {
  239.         if  (!take1[root1->childs[i]->num] && !take2[root2->childs[i]->num]) {
  240.              biection(root1->childs[i], root2->childs[i], ans, take1, take2);
  241.         }
  242.  
  243.     }
  244.     return 1;
  245. }
  246.  
  247. void sort_tree_hash(node* root) {
  248.     std::sort(root->childs.begin(), root->childs.end(), compare_node_by_hash);
  249.     for (auto i : root->childs) {
  250.         sort_tree_hash(i);
  251.     }
  252. }
  253. void print_hash(node* root) {
  254.     cout << root->num << " " << root->hash << endl;
  255.     for (auto i : root->childs) {
  256.         print_hash(i);
  257.     }
  258. }
  259. vector<int> solve() {
  260.     vector<int> ans;
  261.     vector<size_t> center1 = find_center(g1, degree1, v_list1);
  262.     vector<size_t> center2 = find_center(g2, degree2, v_list2);
  263.     if (center1.size() != center2.size()) {
  264.         ans.push_back(-1);
  265.         return ans;
  266.     }
  267.     node* root_parent1 = new node;
  268.     node* root_parent2 = new node;
  269.     node* root1 = constructTreeUtil(center1, degree1, v_list1, root_parent1);
  270.     node* root2 = constructTreeUtil(center2, degree2, v_list2, root_parent1);
  271.     //std::random_shuffle(primes.begin(), primes.end());
  272.     hash_tree(root1);
  273.     hash_tree(root2);
  274.     // print_hash(root1);
  275.     // cout <<endl;
  276.     // print_hash(root2);
  277.     if (root1->hash != root2->hash) {
  278.         ans.push_back(-1);
  279.         return ans;
  280.     }
  281.     ans.resize(n_ + 1);
  282.     vector<bool> take1, take2;
  283.     take1.resize(n_ + 1);
  284.     take2.resize(n_ + 1);
  285.     //sort_tree_hash(root1);
  286.     //sort_tree_hash(root2);
  287.     if (!biection(root1, root2, ans, take1, take2)) {
  288.         ans.clear();
  289.         ans.push_back(-1);
  290.         return ans;
  291.     }
  292.     //biection(root1, root2, ans, take1, take2);
  293.     delete root1;
  294.     delete root2;
  295.     delete root_parent1;
  296.     delete root_parent2;
  297.     ans.erase(ans.begin());
  298.     ans.pop_back();
  299.     return ans;
  300. }
  301.  
  302. /////////////////////////////////////////////////////////////////////
  303. vector<edge> MakeTree(size_t num_vertex, size_t tree_index = 0) {
  304.     vector<edge> roads;
  305.     for (size_t city_name = num_vertex - 1; city_name > 0; --city_name) {
  306.         size_t next_city = tree_index % city_name;
  307.         edge tmp(next_city + 1, city_name + 1);
  308.         roads.emplace_back(tmp);
  309.         tree_index /= city_name;
  310.     }
  311.     return roads;
  312. };
  313.  
  314. vector<edge> PermutateTree(vector<edge> Tree) {
  315.     vector<size_t> indexes;
  316.     for (size_t index = 0; index <= Tree.size(); ++index) {
  317.         indexes.push_back(index);
  318.     }
  319.     std::random_shuffle(indexes.begin(), indexes.end());
  320.     /*for (auto ind : indexes) {
  321.      std::cout << ind + 1 << "\n";
  322.      }*/
  323.    
  324.     for (auto& road : Tree) {
  325.         road.a_ = indexes[road.a_ - 1] + 1;
  326.         road.b_ = indexes[road.b_ - 1] + 1;
  327.     }
  328.    
  329.     std::random_shuffle(Tree.begin(), Tree.end());
  330.    
  331.     return Tree;
  332. };
  333. //////////////////////////////////////////////////////////////////////////
  334. void PrintGr(vector<edge> arr) {
  335.     for (auto i : arr) {
  336.         cout << i.a_ << " " << i.b_ << endl;
  337.     }
  338.     cout<<endl;
  339. };
  340.  
  341. int main(int argc, const char * argv[]) {
  342.     std::ios_base::sync_with_stdio(false);
  343.     std::cin.tie(nullptr);
  344.    
  345.    
  346.     // ///////////////// TESTING ///////////////////////////////////////
  347.     size_t index_end = 1;
  348.     for (size_t tree_size = 10000; tree_size < 10002; ++tree_size) {
  349.         n_ = tree_size;
  350.         for (size_t tree_index = 0; tree_index < 5; ++ tree_index) {
  351.             vector<edge> road_set_one = MakeTree(tree_size, tree_index);
  352.             vector<edge> road_set_two = PermutateTree(road_set_one);
  353.             g1.clear(); g2.clear();
  354.             degree1.clear(); degree2.clear();
  355.             v_list1.clear(); v_list2.clear();
  356.             g1 = road_set_one;
  357.             g2 = road_set_two;
  358.             create_data(g1, g2);
  359.            
  360.             const clock_t begin_time = clock();
  361.             vector<int> ans = solve();
  362.             std::cout << float( clock () - begin_time ) /  CLOCKS_PER_SEC <<endl;
  363.              if (float( clock () - begin_time ) /  CLOCKS_PER_SEC > 1) {
  364.              std::cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<<endl;
  365.              }
  366.  
  367.             if (ans[0] == -1) {
  368.                 std::cout << "ERROR! size = " << tree_size << ", index = " << tree_index << "\n";
  369.                 //PrintGr(g1);
  370.                 //PrintGr(g2);
  371.             } else {
  372.                 //std::cout << "TEST OK" << "\n";
  373.             }
  374.         }
  375.         std::cout << "Size " << tree_size << "done!\n";
  376.          index_end *= tree_size;
  377.     }
  378.     // ///////////////////////////////////////////////////////////////////
  379.     /*read_data();
  380.     vector<int> ans = solve();
  381.     for (auto i : ans) {
  382.         cout << i << endl;
  383.     }*/
  384.     return 0;
  385. }
  386.  
  387. /*10
  388.  5 10
  389.  6 9
  390.  3 8
  391.  3 7
  392.  2 6
  393.  2 5
  394.  1 4
  395.  1 3
  396.  1 2
  397.  
  398.  3 5
  399.  5 2
  400.  7 1
  401.  7 3
  402.  9 4
  403.  9 10
  404.  3 8
  405.  8 6
  406.  7 9*/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement