fork download
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4. using namespace std::chrono;
  5.  
  6. const int DEBUG_MODE = 0;
  7. const int MODE = DEBUG_MODE;
  8. const string LOG_FILE = "log.txt";
  9. const double eps = 1e-9;
  10. const double INF = 1e15;
  11.  
  12. struct Graph {
  13. int n;
  14. vector<vector<pair<int, double>>> adj;
  15. vector<vector<bool>> adj_matrix;
  16. vector<vector<double>> weight_matrix;
  17.  
  18. void init(int _n) {
  19. assert(_n > 0);
  20. n = _n;
  21. adj = vector<vector<pair<int, double>>>(n, vector<pair<int, double>>());
  22. adj_matrix = vector<vector<bool>>(n, vector<bool>(n, false));
  23. weight_matrix = vector<vector<double>>(n, vector<double>(n, 0.0));
  24. }
  25.  
  26. Graph() {
  27. n = 0;
  28. adj.clear();
  29. }
  30.  
  31. Graph(int _n) {
  32. assert(_n > 0);
  33. init(_n);
  34. }
  35.  
  36. void add_edge(int u, int v, double weight) {
  37. assert((0 <= min(u, v)) && (max(u, v) < n));
  38. adj[u].push_back(make_pair(v, weight));
  39. adj[v].push_back(make_pair(u, weight));
  40. weight_matrix[u][v] = weight_matrix[v][u] = weight;
  41. adj_matrix[u][v] = adj_matrix[v][u] = true;
  42. }
  43.  
  44. int get_deg(int u) {
  45. assert((0 <= u) && (u < n));
  46. return adj[u].size();
  47. }
  48.  
  49. bool have_edge(int u, int v) {
  50. assert((0 <= min(u, v)) && (max(u, v) < n));
  51. return adj_matrix[u][v];
  52. }
  53.  
  54. double get_weight(int u, int v) {
  55. assert((0 <= min(u, v)) && (max(u, v) < n));
  56. return weight_matrix[u][v];
  57. }
  58. };
  59.  
  60. struct Tree {
  61. int n, root;
  62. vector<int> par, subtree;
  63. vector<vector<int>> child;
  64. vector<vector<bool>> adj_matrix;
  65.  
  66. void init(int _n, int _root) {
  67. assert(_n > 0);
  68. assert((0 <= _root) && (_root < _n));
  69. n = _n; root = _root;
  70. assert((root >= 0) && (root < n));
  71. par = vector<int>(n, -1); subtree = vector<int>(n, 0);
  72. child = vector<vector<int>>(n, vector<int>());
  73. adj_matrix = vector<vector<bool>>(n, vector<bool>(n, false));
  74. }
  75.  
  76. void append_child(int u, int v) {
  77. assert((0 <= min(u, v)) && (max(u, v) < n));
  78. child[u].push_back(v);
  79. par[v] = u;
  80. adj_matrix[u][v] = adj_matrix[v][u] = true;
  81. }
  82.  
  83. void DFS(int u, int par, Graph &g) {
  84. subtree[u] = 1;
  85. for(pair<int, double> &e : g.adj[u]) {
  86. int v = e.first;
  87. if (v != par) {
  88. append_child(u, v);
  89. DFS(v, u, g);
  90. subtree[u] += subtree[v];
  91. }
  92. }
  93. }
  94.  
  95. void init(Graph &g, int root) {
  96. assert((0 <= root) && (root < g.n));
  97. init(g.n, root);
  98. DFS(root, -1, g);
  99. }
  100.  
  101. Tree() {}
  102. Tree(Graph &g, int root) {
  103. init(g, root);
  104. }
  105.  
  106. int get_num_child(int u) {
  107. assert((0 <= u) && (u < n));
  108. return child[u].size();
  109. }
  110.  
  111. int get_deg(int u) {
  112. assert((0 <= u) && (u < n));
  113. return child[u].size() + (par[u] != -1);
  114. }
  115.  
  116. bool have_edge(int u, int v) {
  117. assert((0 <= min(u, v)) && (max(u, v) < n));
  118. return adj_matrix[u][v];
  119. }
  120. };
  121.  
  122. const int MAXQ = 100 + 10;
  123. const int MAXG = 100 + 10;
  124.  
  125. //input data
  126. Graph G, Q_graph;
  127. Tree Q_tree;
  128. int n_ins; double per_ins;
  129. int n_del; double per_del;
  130. double similar_score[MAXQ][MAXG];
  131. double threshold = 0.0;
  132.  
  133. //variables for algorithm
  134. int n_duplications;
  135. int n_colors;
  136. int color[MAXG];
  137.  
  138. //match result
  139. double best_match_score;
  140. vector<int> inserted_nodes;
  141. vector<int> map_to;
  142.  
  143. void init_log() {
  144. ofstream lf(LOG_FILE);
  145. lf.close();
  146. }
  147.  
  148. inline void write_log(string message) {
  149. ofstream lf(LOG_FILE, std::ofstream::app);
  150. lf << message;
  151. lf.close();
  152. }
  153.  
  154. bool homologous(int q, int v) {
  155. return similar_score[q][v] >= threshold;
  156. }
  157.  
  158. int get_bit(int x, int n) {
  159. return ((x >> n) & 1);
  160. }
  161.  
  162. namespace feedback_vertex_set {
  163. bool DFS(Graph &g, int u, int par, int removed_vertices, vector<bool> &visited) {
  164. if (visited[u])
  165. return true;
  166. visited[u] = true;
  167. for(pair<int, double> &p : g.adj[u]) {
  168. int v = p.first;
  169. if ((v != par) && (get_bit(removed_vertices, v) == 0)) {
  170. if (DFS(g, v, u, removed_vertices, visited))
  171. return true;
  172. }
  173. }
  174. return false;
  175. }
  176.  
  177. bool is_feedback_vertex_set(Graph &g, int vertex_set) {
  178. vector<bool> visited(g.n, false);
  179. for(int v = 0; v < g.n; ++v)
  180. if ((!visited[v]) && (get_bit(vertex_set, v) == 0)) {
  181. bool cycle_found = DFS(g, v, -1, vertex_set, visited);
  182. if (cycle_found) return false;
  183. }
  184. return true;
  185. }
  186.  
  187. vector<int> run(Graph &g) {
  188. for(int vertex_set = 0; vertex_set < (1 << g.n); ++vertex_set) {
  189. if (is_feedback_vertex_set(g, vertex_set)) {
  190. vector<int> feedback_vertex_set;
  191. for(int v = 0; v < g.n; ++v)
  192. if (get_bit(vertex_set, v))
  193. feedback_vertex_set.push_back(v);
  194. return feedback_vertex_set;
  195. }
  196. }
  197. }
  198. }
  199.  
  200. int choose_root(Graph &g) {
  201. for(int i = 0; i < g.n; ++i)
  202. if (g.adj[i].size() == 1)
  203. return i;
  204. return -1;
  205. }
  206.  
  207. namespace graph_to_tree {
  208. vector<int> dup_ver;
  209. vector<vector<int>> dup;
  210. vector<vector<bool>> existing_edges;
  211. vector<pair<int, int>> add_edges;
  212. vector<int> origin;
  213. int n_dup;
  214.  
  215. int DFS(Graph &g, vector<vector<bool>> &existing_edges, int u, vector<int> &par, vector<bool> &visited) {
  216. if (visited[u])
  217. return u;
  218. visited[u] = true;
  219. for(pair<int, double> &p : g.adj[u]) {
  220. int v = p.first;
  221. if ((v != par[u]) && (existing_edges[u][v])) {
  222. par[v] = u;
  223. int x = DFS(g, existing_edges, v, par, visited);
  224. if (x >= 0) return x;
  225. }
  226. }
  227. return -1;
  228. }
  229.  
  230. vector<int> find_a_cycle(Graph &g, vector<vector<bool>> &existing_edges) {
  231. vector<int> par(g.n, -1);
  232. vector<bool> visited(g.n, false);
  233. for(int v = 0; v < g.n; ++v)
  234. if (!visited[v]) {
  235. int u = DFS(g, existing_edges, v, par, visited);
  236. if (u >= 0) {
  237. vector<int> c;
  238. int x = par[u];
  239. while (x != u) {
  240. c.push_back(x);
  241. x = par[x];
  242. }
  243. c.push_back(u);
  244. return c;
  245. }
  246. }
  247. return vector<int>();
  248. }
  249.  
  250. int choose_duplicated_vertex(vector<int> &feedback_vertex_set, vector<int> &cycle) {
  251. for(int u : feedback_vertex_set)
  252. for(int v : cycle)
  253. if (u == v)
  254. return u;
  255. return -1;
  256. }
  257.  
  258. int choose_neighbor_of_duplicated_node(Graph &g, int dup_ver, vector<int> &cycle, vector<vector<bool>> &existing_edges) {
  259. for(pair<int, double> &p : g.adj[dup_ver]) {
  260. int u = p.first;
  261. if (existing_edges[dup_ver][u]) {
  262. for(int v : cycle)
  263. if (u == v)
  264. return u;
  265. }
  266. }
  267. return -1;
  268. }
  269.  
  270. Tree create_tree(Graph &g) {
  271. Graph g_tree(g.n + n_dup);
  272. for(int u = 0; u < g.n; ++u)
  273. for(int v = u + 1; v < g.n; ++v)
  274. if (existing_edges[u][v])
  275. g_tree.add_edge(u, v, 0.0);
  276. for(pair<int, int> &e : add_edges)
  277. g_tree.add_edge(e.first, e.second, 0.0);
  278. int root = choose_root(g_tree);
  279. Tree tree(g_tree, root);
  280. for(int i = 0; i < g_tree.n; ++i)
  281. for(int j = i + 1; j < g_tree.n; ++j)
  282. if (g_tree.have_edge(i, j))
  283. cout << "edge = " << i << " " << j << endl;
  284. return tree;
  285. }
  286.  
  287. Tree run(Graph &g, vector<int> feedback_vertex_set) {
  288. dup = vector<vector<int>>(g.n, vector<int>());
  289. existing_edges = g.adj_matrix;
  290. add_edges.clear();
  291. n_dup = 0;
  292. origin.resize(g.n);
  293. for(int v = 0; v < g.n; ++v) origin[v] = v;
  294. while (true) {
  295. vector<int> cycle = find_a_cycle(g, existing_edges);
  296. if (cycle.size() == 0) break;
  297. cout << "cycle = "; for(int c : cycle) cout << c << " "; cout << "\n";
  298. int dup_ver = choose_duplicated_vertex(feedback_vertex_set, cycle);
  299. cout << "dup_ver = " << dup_ver << endl;
  300. assert(dup_ver >= 0);
  301. int nei = choose_neighbor_of_duplicated_node(g, dup_ver, cycle, existing_edges);
  302. cout << "nei = " << nei << "\n";
  303. assert(nei >= 0);
  304. cout << "index of new vertex = " << g.n + n_dup << endl;
  305. existing_edges[dup_ver][nei] = existing_edges[nei][dup_ver] = false;
  306. dup[dup_ver].push_back(g.n + n_dup);
  307. add_edges.push_back(make_pair(nei, g.n + n_dup));
  308. origin.push_back(dup_ver);
  309. ++n_dup;
  310. }
  311.  
  312. dup_ver.resize(0);
  313. for(int v = 0; v < g.n; ++v)
  314. if (dup[v].size() > 0)
  315. dup_ver.push_back(v);
  316. return create_tree(g);
  317. }
  318. }
  319.  
  320. bool can_delete_general(int q) {
  321. return Q_graph.get_deg(q) == 2;
  322. }
  323.  
  324. bool can_insert_general(int v) {
  325. return true;
  326. //return G.get_deg(v) == 2;
  327. }
  328.  
  329. bool maximize(double &a, double b) {
  330. if (a < b) {
  331. a = b;
  332. return true;
  333. }
  334. else return false;
  335. }
  336.  
  337. string my_to_string(int x) {
  338. if (x == 0) return "0";
  339. string s = "";
  340. bool neg = false;
  341. if (x < 0) {
  342. neg = true;
  343. x = -x;
  344. }
  345. while (x > 0) {
  346. s.push_back(char(int('0') + x % 10));
  347. x /= 10;
  348. }
  349. if (neg) s.push_back('-');
  350. reverse(s.begin(), s.end());
  351. return s;
  352. }
  353.  
  354. string my_double_to_string(double x) {
  355. std::ostringstream strs;
  356. strs << x;
  357. std::string str = strs.str();
  358. return str;
  359. }
  360.  
  361. bool equals(double x, double y) {
  362. return abs(x - y) <= eps;
  363. }
  364.  
  365. namespace tree_match_graph {
  366. Graph G;
  367.  
  368. vector<int> match;
  369. double best_match_score;
  370. int best_root_map_to, best_color_set, best_n_del_left;
  371. vector<int> best_coloring;
  372. vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
  373. vector<vector<vector<double>>> fm_temp;
  374. vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
  375. vector<vector<vector<vector<int>>>> trace_fi_nxt_vertex, trace_fd_nxt_vertex;
  376.  
  377. vector<int> choosed, best_choosed;
  378. vector<bool> can_use_color_set;
  379. double pre_assign_score;
  380.  
  381. //variables stored result
  382. vector<int> inserted_nodes;
  383. vector<int> map_to; //map_to[q] = v => q is map to v; map_to[q] = -1 => q is deleted node
  384.  
  385. double get_similar_score(int q, int v) {
  386. return similar_score[graph_to_tree::origin[q]][v];
  387. }
  388.  
  389. bool can_map(int color_set_use, int v) {
  390. if (!can_use_color_set[color_set_use]) return false;
  391. if (choosed[v] != -1) return true;
  392. return (get_bit(color_set_use, color[v]) == 1);
  393. }
  394.  
  395. bool can_map(int u, int color_set_use, int v) {
  396. int ou = graph_to_tree::origin[u];
  397. if (match[ou] == -1)
  398. return (can_map(color_set_use, v) && homologous(ou, v));
  399. else return (match[ou] == v);
  400. }
  401.  
  402. bool can_delete(int q) {
  403. int oq = graph_to_tree::origin[q];
  404. if (match[oq] != -1) return false;
  405. return (Q_graph.get_deg(oq) == 2);
  406. }
  407.  
  408. bool can_insert(int v) {
  409. return ((G.get_deg(v) == 2) && (choosed[v] == -1));
  410. }
  411.  
  412. int add_vertex(int color_set, int vertex) {
  413. return (choosed[vertex] == -1) ? (color_set + (1 << color[vertex])) : color_set;
  414. }
  415.  
  416. int remove_vertex(int color_set, int vertex) {
  417. return (choosed[vertex] == -1) ? (color_set - (1 << color[vertex])) : color_set;
  418. }
  419.  
  420. void update_fm(int q, int v, int color_set_prev, int n_del_left_prev, int k_th_child, int color_set_on_child, int n_del_left_on_child) {
  421. if (!can_use_color_set[color_set_prev] || !can_use_color_set[color_set_on_child]) return;
  422. if (equals(fm[q][v][color_set_prev][n_del_left_prev], -INF)) return;
  423.  
  424. if (MODE == DEBUG_MODE) write_log("update_fm(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_prev = "
  425. + my_to_string(color_set_prev) + ", n_del_left_prev = " + my_to_string(n_del_left_prev)
  426. + ", k_th_child = " + my_to_string(k_th_child) + ", color_set_on_child = "
  427. + my_to_string(color_set_on_child) + ", n_del_left_on_child = " + my_to_string(n_del_left_on_child) + ")...\n");
  428. int color_set_use = color_set_prev | color_set_on_child;
  429. int n_del_left = n_del_left_prev + n_del_left_on_child;
  430. int child = Q_tree.child[q][k_th_child];
  431. for(pair<int, double> &neighbor : G.adj[v]) {
  432. int u = neighbor.first; double w = neighbor.second;
  433. if (can_map(child, color_set_on_child, u)) {
  434. //map child -> u
  435. if (!equals(fm[child][u][color_set_on_child][n_del_left_on_child], -INF))
  436. if (maximize(fm_temp[v][color_set_use][n_del_left], fm[q][v][color_set_prev][n_del_left_prev]
  437. + fm[child][u][color_set_on_child][n_del_left_on_child] + w))
  438. {
  439. trace_fm_color[q][k_th_child][v][color_set_use][n_del_left] = color_set_on_child;
  440. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left] = n_del_left_on_child;
  441. trace_fm_nxt_vertex[q][k_th_child][v][color_set_use][n_del_left] = u;
  442. };
  443. //insert child
  444. if (can_insert(u) && (!equals(fi[child][u][color_set_on_child][n_del_left_on_child], -INF))) {
  445. if (maximize(fm_temp[v][color_set_use][n_del_left], fm[q][v][color_set_prev][n_del_left_prev]
  446. + fi[child][u][color_set_on_child][n_del_left_on_child] + w))
  447. {
  448. trace_fm_color[q][k_th_child][v][color_set_use][n_del_left] = color_set_on_child;
  449. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left] = n_del_left_on_child;
  450. trace_fm_nxt_vertex[q][k_th_child][v][color_set_use][n_del_left] = - u - 1;
  451. };
  452. }
  453. }
  454. }
  455. if (can_delete(child) && (!equals(fd[child][v][color_set_on_child][n_del_left_on_child], -INF))) {
  456. //delete child
  457. if (maximize(fm_temp[v][color_set_use][n_del_left], fm[q][v][color_set_prev][n_del_left_prev]
  458. + fd[child][v][color_set_on_child][n_del_left_on_child]))
  459. {
  460. trace_fm_color[q][k_th_child][v][color_set_use][n_del_left] = color_set_on_child;
  461. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left] = n_del_left_on_child;
  462. trace_fm_nxt_vertex[q][k_th_child][v][color_set_use][n_del_left] = v; //keep
  463. };
  464. }
  465. if (MODE == DEBUG_MODE) write_log("update_fm(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_prev = "
  466. + my_to_string(color_set_prev) + ", n_del_left_prev = " + my_to_string(n_del_left_prev)
  467. + ", k_th_child = " + my_to_string(k_th_child) + ", color_set_on_child = "
  468. + my_to_string(color_set_on_child) + ", n_del_left_on_child = " + my_to_string(n_del_left_on_child) + ") done\n");
  469. }
  470.  
  471. void update_fm(int q, int k_th_child) {
  472. if (MODE == DEBUG_MODE) write_log("update_fm(q = " + my_to_string(q) + ", k_th_child = " + my_to_string(k_th_child) + ")....\n");
  473. for(int v = 0; v < G.n; ++v)
  474. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  475. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left)
  476. fm_temp[v][color_set][n_del_left] = -INF;
  477.  
  478. for(int color_set_prev = (1 << n_colors) - 1; color_set_prev >= 0; --color_set_prev)
  479. if (can_use_color_set[color_set_prev])
  480. for(int n_del_left_prev = 0; n_del_left_prev <= n_del; ++n_del_left_prev) {
  481. for(int color_set_on_child = 0; color_set_on_child < (1 << n_colors); ++color_set_on_child)
  482. if ((can_use_color_set[color_set_on_child]) &&((color_set_prev + color_set_on_child) == (color_set_prev | color_set_on_child)))
  483. for(int n_del_left_on_child = 0; n_del_left_on_child <= n_del - n_del_left_prev; ++n_del_left_on_child)
  484. for(int v = 0; v < G.n; ++v) {
  485. if (can_map(q, color_set_prev, v))
  486. update_fm(q, v, color_set_prev, n_del_left_prev, k_th_child, color_set_on_child, n_del_left_on_child);
  487. }
  488. }
  489.  
  490. for(int v = 0; v < G.n; ++v)
  491. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  492. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left)
  493. fm[q][v][color_set][n_del_left] = fm_temp[v][color_set][n_del_left];
  494.  
  495. if (MODE == DEBUG_MODE) write_log("update_fm(q = " + my_to_string(q) + ", k_th_child = " + my_to_string(k_th_child) + ") done\n");
  496. }
  497.  
  498. // color[v] belongs to color_set_use
  499. void update_fi(int q, int v, int color_set_use, int n_del_left) {
  500. if (!can_use_color_set[color_set_use]) return;
  501. if (MODE == DEBUG_MODE) write_log("update_fi(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  502. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ")...\n");
  503. int new_color_set = color_set_use - (1 << color[v]);
  504. for(pair<int, double> &neighbor : G.adj[v]) {
  505. int u = neighbor.first; double w = neighbor.second;
  506. if (can_map(new_color_set, u)) {
  507. if (can_map(q, new_color_set, u) && (!equals(fm[q][u][new_color_set][n_del_left], -INF)))
  508. if (maximize(fi[q][v][color_set_use][n_del_left], per_ins + fm[q][u][new_color_set][n_del_left] + w)) {
  509. trace_fi_nxt_vertex[q][v][color_set_use][n_del_left] = u;
  510. };
  511. if (can_insert(u) && (!equals(fi[q][u][new_color_set][n_del_left], -INF))) {
  512. maximize(fi[q][v][color_set_use][n_del_left], per_ins + fi[q][u][new_color_set][n_del_left] + w);
  513. trace_fi_nxt_vertex[q][v][color_set_use][n_del_left] = - u - 1;
  514. }
  515. }
  516. }
  517. if (MODE == DEBUG_MODE) write_log("update_fi(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  518. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ") done\n");
  519. }
  520.  
  521. void update_fi(int q) {
  522. if (MODE == DEBUG_MODE) write_log("update_fi(q = " + my_to_string(q) + ")....\n");
  523. for(int v = 0; v < G.n; ++v)
  524. if (can_insert(v))
  525. for(int color_set_use = 0; color_set_use < (1 << n_colors); ++color_set_use)
  526. if (can_use_color_set[color_set_use])
  527. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left)
  528. if (can_map(color_set_use, v))
  529. update_fi(q, v, color_set_use, n_del_left);
  530. if (MODE == DEBUG_MODE) write_log("update_fi(q = " + my_to_string(q) + ") done\n");
  531. }
  532.  
  533. void update_fd(int q, int v, int color_set_use, int n_del_left) {
  534. if (!can_use_color_set[color_set_use]) return;
  535. if (n_del_left < 1) return;
  536. if (MODE == DEBUG_MODE) write_log("update_fd(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = " + my_to_string(color_set_use)
  537. + ", n_del_left = " + my_to_string(n_del_left) + ")...\n");
  538. int q_nxt = Q_tree.child[q][0];
  539. for(pair<int, double> &neighbor : G.adj[v]) {
  540. int u = neighbor.first; double w = neighbor.second;
  541. if (can_map(color_set_use, u)) {
  542. if (can_map(q_nxt, color_set_use, u) && (!equals(fm[q_nxt][u][color_set_use][n_del_left - 1], -INF))) {
  543. if (maximize(fd[q][v][color_set_use][n_del_left], per_del + fm[q_nxt][u][color_set_use][n_del_left - 1] + w)) {
  544. trace_fd_nxt_vertex[q][v][color_set_use][n_del_left] = u;
  545. };
  546. }
  547. if (!equals(fi[q_nxt][u][color_set_use][n_del_left - 1], -INF)) {
  548. if (maximize(fd[q][v][color_set_use][n_del_left], per_del + fi[q_nxt][u][color_set_use][n_del_left - 1] + w)) {
  549. trace_fd_nxt_vertex[q][v][color_set_use][n_del_left] = - u - 1;
  550. };
  551. }
  552. }
  553. }
  554. if (can_delete(q_nxt) && (n_del_left > 0) && (!equals(fd[q_nxt][v][color_set_use][n_del_left - 1], -INF))) {
  555. if (maximize(fd[q][v][color_set_use][n_del_left], per_del + fd[q_nxt][v][color_set_use][n_del_left - 1])) {
  556. }
  557. trace_fd_nxt_vertex[q][v][color_set_use][n_del_left] = v;
  558. };
  559. }
  560. if (MODE == DEBUG_MODE) write_log("update_fd(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = " + my_to_string(color_set_use)
  561. + ", n_del_left = " + my_to_string(n_del_left) + ") done\n");
  562. }
  563.  
  564. void update_fd(int q) {
  565. if (!can_delete(q)) return;
  566. if (MODE == DEBUG_MODE) write_log("update_fd(q = " + my_to_string(q) + ")....\n");
  567. for(int v = 0; v < G.n; ++v)
  568. for(int color_set_use = 0; color_set_use < (1 << n_colors); ++color_set_use)
  569. if (can_use_color_set[color_set_use])
  570. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left)
  571. update_fd(q, v, color_set_use, n_del_left);
  572. if (MODE == DEBUG_MODE) write_log("update_fd(q = " + my_to_string(q) + ") done\n");
  573. }
  574.  
  575. void init_dp(int q) {
  576. if (MODE == DEBUG_MODE) write_log("init_dp(q = " + my_to_string(q) + ")...\n");
  577.  
  578. for(int v = 0; v < G.n; ++v)
  579. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  580. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left) {
  581. fm[q][v][color_set][n_del_left] = -INF;
  582. fi[q][v][color_set][n_del_left] = -INF;
  583. fd[q][v][color_set][n_del_left] = -INF;
  584. }
  585. for(int v = 0; v < G.n; ++v)
  586. if (can_map(q, (1 << color[v]), v)) {
  587. fm[q][v][add_vertex(0, v)][0] = (match[q] == -1) ? get_similar_score(q, v) : 0.0;
  588. }
  589.  
  590. if (MODE == DEBUG_MODE) write_log("init_dp(q = " + my_to_string(q) + ") done\n");
  591. }
  592.  
  593. void write_log_dp_values(int q) {
  594. write_log("get dp values at node " + my_to_string(q) + "...\n");
  595. write_log("get fm(q = " + my_to_string(q) + ")\n");
  596. for(int v = 0; v < G.n; ++v)
  597. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  598. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left) {
  599. if (!equals(fm[q][v][color_set][n_del_left], -INF))
  600. write_log("fm(" + my_to_string(q) + "," + my_to_string(v) + "," + my_to_string(color_set) + "," + my_to_string(n_del_left) + ") = " + my_double_to_string(fm[q][v][color_set][n_del_left]) + "\n");
  601. }
  602. write_log("get fi(q = " + my_to_string(q) + ")\n");
  603. for(int v = 0; v < G.n; ++v)
  604. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  605. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left) {
  606. if (!equals(fi[q][v][color_set][n_del_left], -INF))
  607. write_log("fi(" + my_to_string(q) + "," + my_to_string(v) + "," + my_to_string(color_set) + "," + my_to_string(n_del_left) + ") = " + my_double_to_string(fi[q][v][color_set][n_del_left]) + "\n");
  608. }
  609. write_log("get fd(q = " + my_to_string(q) + ")\n");
  610. for(int v = 0; v < G.n; ++v)
  611. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  612. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left) {
  613. if (!equals(fd[q][v][color_set][n_del_left], -INF))
  614. write_log("fd(" + my_to_string(q) + "," + my_to_string(v) + "," + my_to_string(color_set) + "," + my_to_string(n_del_left) + ") = " + my_double_to_string(fd[q][v][color_set][n_del_left]) + "\n");
  615. }
  616. write_log("get dp values at node " + my_to_string(q) + " done\n");
  617. }
  618.  
  619. void DFS(int u) {
  620. if (MODE == DEBUG_MODE) write_log("DFS have just enter node " + my_to_string(u) + "\n");
  621. init_dp(u);
  622. for(int k = 0; k < Q_tree.child[u].size(); ++k) {
  623. if (MODE == DEBUG_MODE) write_log("start DFS child " + my_to_string(Q_tree.child[u][k]) + " of " + my_to_string(u) + "\n");
  624. DFS(Q_tree.child[u][k]);
  625. update_fm(u, k);
  626. }
  627. update_fi(u);
  628. update_fd(u);
  629. if (MODE == DEBUG_MODE) write_log("DFS subtree rooted at " + my_to_string(u) + " done\n");
  630.  
  631. if (MODE == DEBUG_MODE) write_log_dp_values(u);
  632. }
  633.  
  634. //forward declaration
  635. void trace_result_matching_fm(int q, int v, int color_set_use, int n_del_left);
  636. void trace_result_matching_fi(int q, int v, int color_set_use, int n_del_left);
  637. void trace_result_matching_fd(int q, int v, int color_set_use, int n_del_left);
  638.  
  639. void trace_result_matching_fm(int q, int v, int color_set_use, int n_del_left) {
  640. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fm(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  641. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ")...\n");
  642. if (MODE == DEBUG_MODE) write_log("with fm = " + my_double_to_string(fm[q][v][color_set_use][n_del_left]));
  643. if (MODE == DEBUG_MODE) write_log("cost match mode " + my_to_string(q) + "->"
  644. + my_to_string(v) + " = " + my_double_to_string(get_similar_score(q, v)) + "\n");
  645. map_to[q] = v;
  646. for(int k_th_child = (int)(Q_tree.child[q].size()) - 1; k_th_child >= 0; --k_th_child) {
  647. int child = Q_tree.child[q][k_th_child];
  648. int u = trace_fm_nxt_vertex[q][k_th_child][v][color_set_use][n_del_left];
  649. if (MODE == DEBUG_MODE) write_log("k_th_child = " + my_to_string(k_th_child)
  650. + ", child = " + my_to_string(child) + ", u = " + my_to_string(u) + "\n");
  651. if (u == v) {
  652. trace_result_matching_fd(child, v, trace_fm_color[q][k_th_child][v][color_set_use][n_del_left],
  653. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left]);
  654. }
  655. else if (u >= 0) {
  656. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(u)
  657. + "=" + my_double_to_string(G.get_weight(v, u)));
  658. trace_result_matching_fm(child, u, trace_fm_color[q][k_th_child][v][color_set_use][n_del_left],
  659. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left]);
  660. }
  661. else { // u < 0
  662. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(-u-1)
  663. + "=" + my_double_to_string(G.get_weight(v, -u-1)));
  664. trace_result_matching_fi(child, -u - 1, trace_fm_color[q][k_th_child][v][color_set_use][n_del_left],
  665. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left]);
  666. }
  667. int nxt_color_set = color_set_use - trace_fm_color[q][k_th_child][v][color_set_use][n_del_left];
  668. int nxt_n_del_left = n_del_left - trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left];
  669. color_set_use = nxt_color_set;
  670. n_del_left = nxt_n_del_left;
  671. }
  672.  
  673. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fm(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  674. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ") done\n");
  675. }
  676.  
  677. void trace_result_matching_fi(int q, int v, int color_set_use, int n_del_left) {
  678. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fi(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  679. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ")...\n");
  680. if (MODE == DEBUG_MODE) write_log("with fi = " + my_double_to_string(fi[q][v][color_set_use][n_del_left]));
  681. inserted_nodes.push_back(v);
  682. int u = trace_fi_nxt_vertex[q][v][color_set_use][n_del_left];
  683. if (MODE == DEBUG_MODE) write_log("u = " + my_to_string(u) + "\n");
  684. if (u >= 0) {
  685. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(u)
  686. + "=" + my_double_to_string(G.get_weight(v, u)));
  687. trace_result_matching_fm(q, u, color_set_use - (1 << color[v]), n_del_left);
  688. }
  689. else { //u < 0
  690. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(-u-1)
  691. + "=" + my_double_to_string(G.get_weight(v, -u-1)));
  692. trace_result_matching_fi(q, -u - 1, color_set_use - (1 << color[v]), n_del_left);
  693. }
  694. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fi(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  695. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ") done\n");
  696. }
  697.  
  698. void trace_result_matching_fd(int q, int v, int color_set_use, int n_del_left) {
  699. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fd(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  700. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ")...\n");
  701. if (MODE == DEBUG_MODE) write_log("with fd = " + my_double_to_string(fd[q][v][color_set_use][n_del_left]));
  702. int u = trace_fd_nxt_vertex[q][v][color_set_use][n_del_left];
  703. if (MODE == DEBUG_MODE) write_log("u = " + my_to_string(u) + "\n");
  704. int q_nxt = Q_tree.child[q][0];
  705. if (u == v) {
  706. trace_result_matching_fd(q_nxt, v, color_set_use, n_del_left - 1);
  707. }
  708. else if (u >= 0) {
  709. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(u)
  710. + "=" + my_double_to_string(G.get_weight(v, u)));
  711. trace_result_matching_fm(q_nxt, u, color_set_use, n_del_left - 1);
  712. }
  713. else { // u < 0
  714. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(-u-1)
  715. + "=" + my_double_to_string(G.get_weight(v, -u-1)));
  716. trace_result_matching_fi(q_nxt, -u - 1, color_set_use, n_del_left - 1);
  717. }
  718. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fd(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  719. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ") done\n");
  720. }
  721.  
  722. void get_result() {
  723. if (MODE == DEBUG_MODE) write_log("get_result()...\n");
  724. double this_best_score = -INF;
  725. int root_map_to = -1, start_color_set = -1, start_n_del_left = -1;
  726. for(int v = 0; v < G.n; ++v)
  727. //map Q.root -> v
  728. for(int color_set_use = 0; color_set_use < (1 << n_colors); ++color_set_use)
  729. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left) {
  730. if ((MODE == DEBUG_MODE) && (!equals(fm[Q_tree.root][v][color_set_use][n_del_left], -INF)))
  731. write_log("fm(" + my_to_string(Q_tree.root) + "," + my_to_string(v) + "," + my_to_string(color_set_use) + "," + my_to_string(n_del_left) + ") = " + my_double_to_string(fm[Q_tree.root][v][color_set_use][n_del_left]) + "\n");
  732. if (maximize(this_best_score, fm[Q_tree.root][v][color_set_use][n_del_left])) {
  733. root_map_to = v;
  734. start_color_set = color_set_use;
  735. start_n_del_left = n_del_left;
  736. };
  737. }
  738. if (!equals(this_best_score, -INF)) this_best_score += pre_assign_score;
  739.  
  740. if (maximize(best_match_score, this_best_score)) {
  741. best_root_map_to = root_map_to;
  742. best_color_set = start_color_set;
  743. best_n_del_left = start_n_del_left;
  744. for(int v = 0; v < G.n; ++v) {
  745. best_coloring[v] = color[v];
  746. best_choosed[v] = choosed[v];
  747. }
  748. };
  749. //cout << "this_best_score = " << this_best_score << endl;
  750. if (MODE == DEBUG_MODE) write_log("this_best_score = " + my_double_to_string(this_best_score) + "\n");
  751. if (MODE == DEBUG_MODE) write_log("best_match_score = " + my_double_to_string(best_match_score) + "\n");
  752. if (MODE == DEBUG_MODE) write_log("get_result() done\n");
  753. }
  754.  
  755. void random_coloring() {
  756. if (MODE == DEBUG_MODE) write_log("start random coloring...\n");
  757. for(int v = 0; v < G.n; ++v) {
  758. color[v] = v % n_colors; //rnd.next(0, n_colors - 1); //rand() % n_colors;
  759. if (MODE == DEBUG_MODE) write_log("color(" + my_to_string(v) + ") = " + my_to_string(color[v]) + "\n");
  760. }
  761. if (MODE == DEBUG_MODE) write_log("random coloring done\n");
  762. }
  763.  
  764. void init_before_dp_on_tree() {
  765. can_use_color_set.resize((1 << n_colors));
  766. for(int color_set = 0; color_set < (1 << n_colors); ++color_set) {
  767. bool ok = true;
  768. for(int v = 0; v < G.n; ++v)
  769. if (choosed[v] != -1)
  770. if (get_bit(color_set, color[v]) == 1)
  771. ok = false;
  772. can_use_color_set[color_set] = ok;
  773. }
  774. pre_assign_score = 0.0;
  775. for(int q = 0; q < Q_graph.n; ++q)
  776. if (match[q] != -1)
  777. pre_assign_score += get_similar_score(q, match[q]);
  778. cout << "pre_assign_score = " << pre_assign_score << endl;
  779. }
  780.  
  781. void dp_on_tree() {
  782.  
  783. for(int i = 0; i < G.n; ++i) cout << "color(" << i << ") = " << color[i] << endl;
  784. for(int i = 0; i < Q_graph.n; ++i)
  785. if (match[i] != -1) cout << i << "->" << match[i] << endl;
  786.  
  787. init_before_dp_on_tree();
  788. if (MODE == DEBUG_MODE) write_log("start DFS from Q_tree.root = " + my_to_string(Q_tree.root) + "\n");
  789. DFS(Q_tree.root);
  790. if (MODE == DEBUG_MODE) write_log("DFS done\n");
  791. get_result();
  792. cout << "1 phase dp done\n";
  793. }
  794.  
  795. void backtrack_assign(int qi, int set_choosed) {
  796. if (qi >= graph_to_tree::dup_ver.size()) {
  797. dp_on_tree();
  798. return;
  799. }
  800.  
  801. int q = graph_to_tree::dup_ver[qi];
  802. for(int v = 0; v < G.n; ++v)
  803. if ((choosed[v] == -1) && (get_bit(set_choosed, color[v]) == 0) && (G.get_deg(v) >= Q_graph.get_deg(qi) - n_del)) {
  804. choosed[v] = q;
  805. match[q] = v;
  806. backtrack_assign(qi + 1, set_choosed + (1 << color[v]));
  807. choosed[v] = -1;
  808. match[q] = -1;
  809. }
  810. }
  811.  
  812. void pre_assignment() {
  813. choosed.resize(G.n); best_choosed.resize(G.n);
  814. for(int v = 0; v < G.n; ++v) choosed[v] = -1;
  815. match.resize(Q_graph.n);
  816. for(int q = 0; q < match.size(); ++q) match[q] = -1;
  817. //backtrack_assign(0, 0);
  818. match[1] = 2; choosed[2] = 1; dp_on_tree();
  819. }
  820.  
  821. void run() {
  822. random_coloring();
  823. cout << "random coloring done\n";
  824. pre_assignment();
  825. }
  826.  
  827. void init_trace_best_matching() {
  828. for(int v = 0; v < G.n; ++v) color[v] = best_coloring[v];
  829. choosed = best_choosed;
  830. for(int q = 0; q < Q_graph.n; ++q)
  831. match[q] = -1;
  832. for(int v = 0; v < G.n; ++v)
  833. if (choosed[v] != -1)
  834. match[choosed[v]] = v;
  835. init_before_dp_on_tree();
  836. DFS(Q_tree.root);
  837. }
  838.  
  839. void trace_best_matching() {
  840. inserted_nodes.resize(0);
  841. map_to = vector<int>(Q_tree.n, -1);
  842. if (MODE == DEBUG_MODE) write_log("start trace best matching...\n");
  843. if (equals(best_match_score, -INF)) {
  844. cout << "No matching found!\n";
  845. write_log("No matching found!\n");
  846. if (MODE == DEBUG_MODE) write_log("No matching found!\ntrace best matching done\n");
  847. return;
  848. }
  849.  
  850. write_log("best_match_score(in a connected component) = " + my_to_string(best_match_score) + "\n");
  851. cout << "trace result with best_match_score = " << best_match_score << endl;
  852.  
  853. init_trace_best_matching();
  854.  
  855. trace_result_matching_fm(Q_tree.root, best_root_map_to, best_color_set, best_n_del_left);
  856. if (MODE == DEBUG_MODE) write_log("trace best matching done\n");
  857. write_log("map_to = {");
  858. for(int q = 0; q < Q_tree.n; ++q) write_log(my_to_string(map_to[q]) + ",");
  859. write_log("}\n");
  860. write_log("inserted_nodes = {");
  861. for(int v : inserted_nodes) write_log(my_to_string(v) + ",");
  862. write_log("}\n");
  863. }
  864.  
  865. void init_vector(vector<vector<vector<double>>> &v, int dim1, int dim2, int dim3, double val) {
  866. assert(min(dim1, min(dim2, dim3)) >= 0);
  867. v.resize(dim1);
  868. for(int i = 0; i < dim1; ++i) {
  869. v[i].resize(dim2);
  870. for(int j = 0; j < dim2; ++j) {
  871. v[i][j].resize(dim3);
  872. for(int k = 0; k < dim3; ++k) {
  873. v[i][j][k] = val;
  874. }
  875. }
  876. }
  877. }
  878.  
  879. void init_vector(vector<vector<vector<vector<double>>>> &v, int dim1, int dim2, int dim3, int dim4, double val) {
  880. assert(min(dim1, min(dim2, min(dim3, dim4))) >= 0);
  881. cout << "4 dims = " << dim1 << " " << dim2 << " " << dim3 << " " << dim4 << " " << dim1 * dim2 * dim3 * dim4 << endl;
  882. v.resize(dim1);
  883. for(int i = 0; i < dim1; ++i) {
  884. v[i].resize(dim2);
  885. for(int j = 0; j < dim2; ++j) {
  886. v[i][j].resize(dim3);
  887. for(int k = 0; k < dim3; ++k) {
  888. v[i][j][k].resize(dim4);
  889. for(int t = 0; t < dim4; ++t)
  890. v[i][j][k][t] = val;
  891. }
  892. }
  893. }
  894. }
  895.  
  896. void init_vector(vector<vector<vector<vector<int>>>> &v, int dim1, int dim2, int dim3, int dim4, int val) {
  897. assert(min(dim1, min(dim2, min(dim3, dim4))) >= 0);
  898. v.resize(dim1);
  899. for(int i = 0; i < dim1; ++i) {
  900. v[i].resize(dim2);
  901. for(int j = 0; j < dim2; ++j) {
  902. v[i][j].resize(dim3);
  903. for(int k = 0; k < dim3; ++k) {
  904. v[i][j][k].resize(dim4);
  905. for(int t = 0; t < dim4; ++t)
  906. v[i][j][k][t] = val;
  907. }
  908. }
  909. }
  910. }
  911.  
  912. void init_vector(vector<vector<vector<vector<vector<int>>>>> &v, int dim1, int dim2, int dim3, int dim4, int dim5, double val) {
  913. assert(min(dim1, min(dim2, min(dim3, min(dim4, dim5)))) >= 0);
  914. v.resize(dim1);
  915. for(int i = 0; i < dim1; ++i) {
  916. v[i].resize(dim2);
  917. for(int j = 0; j < dim2; ++j) {
  918. v[i][j].resize(dim3);
  919. for(int k = 0; k < dim3; ++k) {
  920. v[i][j][k].resize(dim4);
  921. for(int t = 0; t < dim4; ++t) {
  922. v[i][j][k][t].resize(dim5);
  923. for(int u = 0; u < dim5; ++u)
  924. v[i][j][k][t][u] = val;
  925. }
  926. }
  927. }
  928. }
  929. }
  930.  
  931.  
  932. void init_vector_dimension() {
  933. init_vector(fm, Q_tree.n, G.n, (1 << n_colors), n_del + 1, -INF);
  934. init_vector(fi, Q_tree.n, G.n, (1 << n_colors), n_del + 1, -INF);
  935. init_vector(fd, Q_tree.n, G.n, (1 << n_colors), n_del + 1, -INF);
  936.  
  937. init_vector(fm_temp, G.n, (1 << n_colors), n_del + 1, -INF);
  938.  
  939. trace_fm_color.resize(Q_tree.n);
  940. trace_fm_n_del_left.resize(Q_tree.n);
  941. trace_fm_nxt_vertex.resize(Q_tree.n);
  942.  
  943. init_vector(trace_fi_nxt_vertex, Q_tree.n, G.n, (1 << n_colors), n_del + 1, -1);
  944. init_vector(trace_fd_nxt_vertex, Q_tree.n, G.n, (1 << n_colors), n_del + 1, -1);
  945.  
  946. for(int u = 0; u < Q_tree.n; ++u) {
  947. init_vector(trace_fm_color[u], Q_tree.get_num_child(u), G.n, (1 << n_colors), n_del + 1, -1);
  948. init_vector(trace_fm_n_del_left[u], Q_tree.get_num_child(u), G.n, (1 << n_colors), n_del + 1, -1);
  949. init_vector(trace_fm_nxt_vertex[u], Q_tree.get_num_child(u), G.n, (1 << n_colors), n_del + 1, -1);
  950. }
  951. }
  952.  
  953. void solve() {
  954. cout << "enter solve()\n";
  955. init_vector_dimension();
  956. cout << "init dim done\n";
  957. int n_loops = 1;
  958. best_match_score = -INF;
  959. best_coloring.resize(G.n);
  960. cout << "while loop\n";
  961. while (n_loops > 0) {
  962. n_loops--;
  963. if (MODE == DEBUG_MODE) write_log("n_loops = " + my_to_string(n_loops));
  964. run();
  965. if (MODE == DEBUG_MODE) write_log("run() done\n");
  966. }
  967. trace_best_matching();
  968. }
  969.  
  970. void set_graph(Graph &g) {
  971. G = g;
  972. }
  973. }
  974.  
  975. namespace tree_match_graph {
  976. Graph G;
  977.  
  978. vector<int> match;
  979. double best_match_score;
  980. int best_root_map_to, best_color_set, best_n_del_left;
  981. vector<int> best_coloring;
  982. vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
  983. vector<vector<vector<double>>> fm_temp;
  984. vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
  985. vector<vector<vector<vector<int>>>> trace_fi_nxt_vertex, trace_fd_nxt_vertex;
  986.  
  987. vector<int> choosed, best_choosed;
  988. vector<bool> can_use_color_set;
  989. double pre_assign_score;
  990.  
  991. //variables stored result
  992. vector<int> inserted_nodes;
  993. vector<int> map_to; //map_to[q] = v => q is map to v; map_to[q] = -1 => q is deleted node
  994.  
  995. double get_similar_score(int q, int v) {
  996. return similar_score[graph_to_tree::origin[q]][v];
  997. }
  998.  
  999. bool can_map(int color_set_use, int v) {
  1000. if (!can_use_color_set[color_set_use]) return false;
  1001. if (choosed[v] != -1) return true;
  1002. return (get_bit(color_set_use, color[v]) == 1);
  1003. }
  1004.  
  1005. bool can_map(int u, int color_set_use, int v) {
  1006. int ou = graph_to_tree::origin[u];
  1007. if (match[ou] == -1)
  1008. return (can_map(color_set_use, v) && homologous(ou, v));
  1009. else return (match[ou] == v);
  1010. }
  1011.  
  1012. bool can_delete(int q) {
  1013. int oq = graph_to_tree::origin[q];
  1014. if (match[oq] != -1) return false;
  1015. return (Q_graph.get_deg(oq) == 2);
  1016. }
  1017.  
  1018. bool can_insert(int v) {
  1019. return ((G.get_deg(v) == 2) && (choosed[v] == -1));
  1020. }
  1021.  
  1022. int add_vertex(int color_set, int vertex) {
  1023. return (choosed[vertex] == -1) ? (color_set + (1 << color[vertex])) : color_set;
  1024. }
  1025.  
  1026. int remove_vertex(int color_set, int vertex) {
  1027. return (choosed[vertex] == -1) ? (color_set - (1 << color[vertex])) : color_set;
  1028. }
  1029.  
  1030. void update_fm(int q, int v, int color_set_prev, int n_del_left_prev, int k_th_child, int color_set_on_child, int n_del_left_on_child) {
  1031. if (!can_use_color_set[color_set_prev] || !can_use_color_set[color_set_on_child]) return;
  1032. if (equals(fm[q][v][color_set_prev][n_del_left_prev], -INF)) return;
  1033.  
  1034. if (MODE == DEBUG_MODE) write_log("update_fm(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_prev = "
  1035. + my_to_string(color_set_prev) + ", n_del_left_prev = " + my_to_string(n_del_left_prev)
  1036. + ", k_th_child = " + my_to_string(k_th_child) + ", color_set_on_child = "
  1037. + my_to_string(color_set_on_child) + ", n_del_left_on_child = " + my_to_string(n_del_left_on_child) + ")...\n");
  1038. int color_set_use = color_set_prev | color_set_on_child;
  1039. int n_del_left = n_del_left_prev + n_del_left_on_child;
  1040. int child = Q_tree.child[q][k_th_child];
  1041. for(pair<int, double> &neighbor : G.adj[v]) {
  1042. int u = neighbor.first; double w = neighbor.second;
  1043. if (can_map(child, color_set_on_child, u)) {
  1044. //map child -> u
  1045. if (!equals(fm[child][u][color_set_on_child][n_del_left_on_child], -INF))
  1046. if (maximize(fm_temp[v][color_set_use][n_del_left], fm[q][v][color_set_prev][n_del_left_prev]
  1047. + fm[child][u][color_set_on_child][n_del_left_on_child] + w))
  1048. {
  1049. trace_fm_color[q][k_th_child][v][color_set_use][n_del_left] = color_set_on_child;
  1050. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left] = n_del_left_on_child;
  1051. trace_fm_nxt_vertex[q][k_th_child][v][color_set_use][n_del_left] = u;
  1052. };
  1053. //insert child
  1054. if (can_insert(u) && (!equals(fi[child][u][color_set_on_child][n_del_left_on_child], -INF))) {
  1055. if (maximize(fm_temp[v][color_set_use][n_del_left], fm[q][v][color_set_prev][n_del_left_prev]
  1056. + fi[child][u][color_set_on_child][n_del_left_on_child] + w))
  1057. {
  1058. trace_fm_color[q][k_th_child][v][color_set_use][n_del_left] = color_set_on_child;
  1059. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left] = n_del_left_on_child;
  1060. trace_fm_nxt_vertex[q][k_th_child][v][color_set_use][n_del_left] = - u - 1;
  1061. };
  1062. }
  1063. }
  1064. }
  1065. if (can_delete(child) && (!equals(fd[child][v][color_set_on_child][n_del_left_on_child], -INF))) {
  1066. //delete child
  1067. if (maximize(fm_temp[v][color_set_use][n_del_left], fm[q][v][color_set_prev][n_del_left_prev]
  1068. + fd[child][v][color_set_on_child][n_del_left_on_child]))
  1069. {
  1070. trace_fm_color[q][k_th_child][v][color_set_use][n_del_left] = color_set_on_child;
  1071. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left] = n_del_left_on_child;
  1072. trace_fm_nxt_vertex[q][k_th_child][v][color_set_use][n_del_left] = v; //keep
  1073. };
  1074. }
  1075. if (MODE == DEBUG_MODE) write_log("update_fm(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_prev = "
  1076. + my_to_string(color_set_prev) + ", n_del_left_prev = " + my_to_string(n_del_left_prev)
  1077. + ", k_th_child = " + my_to_string(k_th_child) + ", color_set_on_child = "
  1078. + my_to_string(color_set_on_child) + ", n_del_left_on_child = " + my_to_string(n_del_left_on_child) + ") done\n");
  1079. }
  1080.  
  1081. void update_fm(int q, int k_th_child) {
  1082. if (MODE == DEBUG_MODE) write_log("update_fm(q = " + my_to_string(q) + ", k_th_child = " + my_to_string(k_th_child) + ")....\n");
  1083. for(int v = 0; v < G.n; ++v)
  1084. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  1085. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left)
  1086. fm_temp[v][color_set][n_del_left] = -INF;
  1087.  
  1088. for(int color_set_prev = (1 << n_colors) - 1; color_set_prev >= 0; --color_set_prev)
  1089. if (can_use_color_set[color_set_prev])
  1090. for(int n_del_left_prev = 0; n_del_left_prev <= n_del; ++n_del_left_prev) {
  1091. for(int color_set_on_child = 0; color_set_on_child < (1 << n_colors); ++color_set_on_child)
  1092. if ((can_use_color_set[color_set_on_child]) &&((color_set_prev + color_set_on_child) == (color_set_prev | color_set_on_child)))
  1093. for(int n_del_left_on_child = 0; n_del_left_on_child <= n_del - n_del_left_prev; ++n_del_left_on_child)
  1094. for(int v = 0; v < G.n; ++v) {
  1095. if (can_map(q, color_set_prev, v))
  1096. update_fm(q, v, color_set_prev, n_del_left_prev, k_th_child, color_set_on_child, n_del_left_on_child);
  1097. }
  1098. }
  1099.  
  1100. for(int v = 0; v < G.n; ++v)
  1101. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  1102. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left)
  1103. fm[q][v][color_set][n_del_left] = fm_temp[v][color_set][n_del_left];
  1104.  
  1105. if (MODE == DEBUG_MODE) write_log("update_fm(q = " + my_to_string(q) + ", k_th_child = " + my_to_string(k_th_child) + ") done\n");
  1106. }
  1107.  
  1108. // color[v] belongs to color_set_use
  1109. void update_fi(int q, int v, int color_set_use, int n_del_left) {
  1110. if (!can_use_color_set[color_set_use]) return;
  1111. if (MODE == DEBUG_MODE) write_log("update_fi(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  1112. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ")...\n");
  1113. int new_color_set = color_set_use - (1 << color[v]);
  1114. for(pair<int, double> &neighbor : G.adj[v]) {
  1115. int u = neighbor.first; double w = neighbor.second;
  1116. if (can_map(new_color_set, u)) {
  1117. if (can_map(q, new_color_set, u) && (!equals(fm[q][u][new_color_set][n_del_left], -INF)))
  1118. if (maximize(fi[q][v][color_set_use][n_del_left], per_ins + fm[q][u][new_color_set][n_del_left] + w)) {
  1119. trace_fi_nxt_vertex[q][v][color_set_use][n_del_left] = u;
  1120. };
  1121. if (can_insert(u) && (!equals(fi[q][u][new_color_set][n_del_left], -INF))) {
  1122. maximize(fi[q][v][color_set_use][n_del_left], per_ins + fi[q][u][new_color_set][n_del_left] + w);
  1123. trace_fi_nxt_vertex[q][v][color_set_use][n_del_left] = - u - 1;
  1124. }
  1125. }
  1126. }
  1127. if (MODE == DEBUG_MODE) write_log("update_fi(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  1128. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ") done\n");
  1129. }
  1130.  
  1131. void update_fi(int q) {
  1132. if (MODE == DEBUG_MODE) write_log("update_fi(q = " + my_to_string(q) + ")....\n");
  1133. for(int v = 0; v < G.n; ++v)
  1134. if (can_insert(v))
  1135. for(int color_set_use = 0; color_set_use < (1 << n_colors); ++color_set_use)
  1136. if (can_use_color_set[color_set_use])
  1137. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left)
  1138. if (can_map(color_set_use, v))
  1139. update_fi(q, v, color_set_use, n_del_left);
  1140. if (MODE == DEBUG_MODE) write_log("update_fi(q = " + my_to_string(q) + ") done\n");
  1141. }
  1142.  
  1143. void update_fd(int q, int v, int color_set_use, int n_del_left) {
  1144. if (!can_use_color_set[color_set_use]) return;
  1145. if (n_del_left < 1) return;
  1146. if (MODE == DEBUG_MODE) write_log("update_fd(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = " + my_to_string(color_set_use)
  1147. + ", n_del_left = " + my_to_string(n_del_left) + ")...\n");
  1148. int q_nxt = Q_tree.child[q][0];
  1149. for(pair<int, double> &neighbor : G.adj[v]) {
  1150. int u = neighbor.first; double w = neighbor.second;
  1151. if (can_map(color_set_use, u)) {
  1152. if (can_map(q_nxt, color_set_use, u) && (!equals(fm[q_nxt][u][color_set_use][n_del_left - 1], -INF))) {
  1153. if (maximize(fd[q][v][color_set_use][n_del_left], per_del + fm[q_nxt][u][color_set_use][n_del_left - 1] + w)) {
  1154. trace_fd_nxt_vertex[q][v][color_set_use][n_del_left] = u;
  1155. };
  1156. }
  1157. if (!equals(fi[q_nxt][u][color_set_use][n_del_left - 1], -INF)) {
  1158. if (maximize(fd[q][v][color_set_use][n_del_left], per_del + fi[q_nxt][u][color_set_use][n_del_left - 1] + w)) {
  1159. trace_fd_nxt_vertex[q][v][color_set_use][n_del_left] = - u - 1;
  1160. };
  1161. }
  1162. }
  1163. }
  1164. if (can_delete(q_nxt) && (n_del_left > 0) && (!equals(fd[q_nxt][v][color_set_use][n_del_left - 1], -INF))) {
  1165. if (maximize(fd[q][v][color_set_use][n_del_left], per_del + fd[q_nxt][v][color_set_use][n_del_left - 1])) {
  1166. }
  1167. trace_fd_nxt_vertex[q][v][color_set_use][n_del_left] = v;
  1168. };
  1169. }
  1170. if (MODE == DEBUG_MODE) write_log("update_fd(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = " + my_to_string(color_set_use)
  1171. + ", n_del_left = " + my_to_string(n_del_left) + ") done\n");
  1172. }
  1173.  
  1174. void update_fd(int q) {
  1175. if (!can_delete(q)) return;
  1176. if (MODE == DEBUG_MODE) write_log("update_fd(q = " + my_to_string(q) + ")....\n");
  1177. for(int v = 0; v < G.n; ++v)
  1178. for(int color_set_use = 0; color_set_use < (1 << n_colors); ++color_set_use)
  1179. if (can_use_color_set[color_set_use])
  1180. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left)
  1181. update_fd(q, v, color_set_use, n_del_left);
  1182. if (MODE == DEBUG_MODE) write_log("update_fd(q = " + my_to_string(q) + ") done\n");
  1183. }
  1184.  
  1185. void init_dp(int q) {
  1186. if (MODE == DEBUG_MODE) write_log("init_dp(q = " + my_to_string(q) + ")...\n");
  1187.  
  1188. for(int v = 0; v < G.n; ++v)
  1189. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  1190. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left) {
  1191. fm[q][v][color_set][n_del_left] = -INF;
  1192. fi[q][v][color_set][n_del_left] = -INF;
  1193. fd[q][v][color_set][n_del_left] = -INF;
  1194. }
  1195. for(int v = 0; v < G.n; ++v)
  1196. if (can_map(q, (1 << color[v]), v)) {
  1197. fm[q][v][add_vertex(0, v)][0] = (match[q] == -1) ? get_similar_score(q, v) : 0.0;
  1198. }
  1199.  
  1200. if (MODE == DEBUG_MODE) write_log("init_dp(q = " + my_to_string(q) + ") done\n");
  1201. }
  1202.  
  1203. void write_log_dp_values(int q) {
  1204. write_log("get dp values at node " + my_to_string(q) + "...\n");
  1205. write_log("get fm(q = " + my_to_string(q) + ")\n");
  1206. for(int v = 0; v < G.n; ++v)
  1207. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  1208. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left) {
  1209. if (!equals(fm[q][v][color_set][n_del_left], -INF))
  1210. write_log("fm(" + my_to_string(q) + "," + my_to_string(v) + "," + my_to_string(color_set) + "," + my_to_string(n_del_left) + ") = " + my_double_to_string(fm[q][v][color_set][n_del_left]) + "\n");
  1211. }
  1212. write_log("get fi(q = " + my_to_string(q) + ")\n");
  1213. for(int v = 0; v < G.n; ++v)
  1214. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  1215. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left) {
  1216. if (!equals(fi[q][v][color_set][n_del_left], -INF))
  1217. write_log("fi(" + my_to_string(q) + "," + my_to_string(v) + "," + my_to_string(color_set) + "," + my_to_string(n_del_left) + ") = " + my_double_to_string(fi[q][v][color_set][n_del_left]) + "\n");
  1218. }
  1219. write_log("get fd(q = " + my_to_string(q) + ")\n");
  1220. for(int v = 0; v < G.n; ++v)
  1221. for(int color_set = 0; color_set < (1 << n_colors); ++color_set)
  1222. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left) {
  1223. if (!equals(fd[q][v][color_set][n_del_left], -INF))
  1224. write_log("fd(" + my_to_string(q) + "," + my_to_string(v) + "," + my_to_string(color_set) + "," + my_to_string(n_del_left) + ") = " + my_double_to_string(fd[q][v][color_set][n_del_left]) + "\n");
  1225. }
  1226. write_log("get dp values at node " + my_to_string(q) + " done\n");
  1227. }
  1228.  
  1229. void DFS(int u) {
  1230. if (MODE == DEBUG_MODE) write_log("DFS have just enter node " + my_to_string(u) + "\n");
  1231. init_dp(u);
  1232. for(int k = 0; k < Q_tree.child[u].size(); ++k) {
  1233. if (MODE == DEBUG_MODE) write_log("start DFS child " + my_to_string(Q_tree.child[u][k]) + " of " + my_to_string(u) + "\n");
  1234. DFS(Q_tree.child[u][k]);
  1235. update_fm(u, k);
  1236. }
  1237. update_fi(u);
  1238. update_fd(u);
  1239. if (MODE == DEBUG_MODE) write_log("DFS subtree rooted at " + my_to_string(u) + " done\n");
  1240.  
  1241. if (MODE == DEBUG_MODE) write_log_dp_values(u);
  1242. }
  1243.  
  1244. //forward declaration
  1245. void trace_result_matching_fm(int q, int v, int color_set_use, int n_del_left);
  1246. void trace_result_matching_fi(int q, int v, int color_set_use, int n_del_left);
  1247. void trace_result_matching_fd(int q, int v, int color_set_use, int n_del_left);
  1248.  
  1249. void trace_result_matching_fm(int q, int v, int color_set_use, int n_del_left) {
  1250. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fm(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  1251. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ")...\n");
  1252. if (MODE == DEBUG_MODE) write_log("with fm = " + my_double_to_string(fm[q][v][color_set_use][n_del_left]));
  1253. if (MODE == DEBUG_MODE) write_log("cost match mode " + my_to_string(q) + "->"
  1254. + my_to_string(v) + " = " + my_double_to_string(get_similar_score(q, v)) + "\n");
  1255. map_to[q] = v;
  1256. for(int k_th_child = (int)(Q_tree.child[q].size()) - 1; k_th_child >= 0; --k_th_child) {
  1257. int child = Q_tree.child[q][k_th_child];
  1258. int u = trace_fm_nxt_vertex[q][k_th_child][v][color_set_use][n_del_left];
  1259. if (MODE == DEBUG_MODE) write_log("k_th_child = " + my_to_string(k_th_child)
  1260. + ", child = " + my_to_string(child) + ", u = " + my_to_string(u) + "\n");
  1261. if (u == v) {
  1262. trace_result_matching_fd(child, v, trace_fm_color[q][k_th_child][v][color_set_use][n_del_left],
  1263. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left]);
  1264. }
  1265. else if (u >= 0) {
  1266. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(u)
  1267. + "=" + my_double_to_string(G.get_weight(v, u)));
  1268. trace_result_matching_fm(child, u, trace_fm_color[q][k_th_child][v][color_set_use][n_del_left],
  1269. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left]);
  1270. }
  1271. else { // u < 0
  1272. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(-u-1)
  1273. + "=" + my_double_to_string(G.get_weight(v, -u-1)));
  1274. trace_result_matching_fi(child, -u - 1, trace_fm_color[q][k_th_child][v][color_set_use][n_del_left],
  1275. trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left]);
  1276. }
  1277. int nxt_color_set = color_set_use - trace_fm_color[q][k_th_child][v][color_set_use][n_del_left];
  1278. int nxt_n_del_left = n_del_left - trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left];
  1279. color_set_use = nxt_color_set;
  1280. n_del_left = nxt_n_del_left;
  1281. }
  1282.  
  1283. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fm(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  1284. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ") done\n");
  1285. }
  1286.  
  1287. void trace_result_matching_fi(int q, int v, int color_set_use, int n_del_left) {
  1288. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fi(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  1289. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ")...\n");
  1290. if (MODE == DEBUG_MODE) write_log("with fi = " + my_double_to_string(fi[q][v][color_set_use][n_del_left]));
  1291. inserted_nodes.push_back(v);
  1292. int u = trace_fi_nxt_vertex[q][v][color_set_use][n_del_left];
  1293. if (MODE == DEBUG_MODE) write_log("u = " + my_to_string(u) + "\n");
  1294. if (u >= 0) {
  1295. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(u)
  1296. + "=" + my_double_to_string(G.get_weight(v, u)));
  1297. trace_result_matching_fm(q, u, color_set_use - (1 << color[v]), n_del_left);
  1298. }
  1299. else { //u < 0
  1300. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(-u-1)
  1301. + "=" + my_double_to_string(G.get_weight(v, -u-1)));
  1302. trace_result_matching_fi(q, -u - 1, color_set_use - (1 << color[v]), n_del_left);
  1303. }
  1304. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fi(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  1305. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ") done\n");
  1306. }
  1307.  
  1308. void trace_result_matching_fd(int q, int v, int color_set_use, int n_del_left) {
  1309. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fd(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  1310. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ")...\n");
  1311. if (MODE == DEBUG_MODE) write_log("with fd = " + my_double_to_string(fd[q][v][color_set_use][n_del_left]));
  1312. int u = trace_fd_nxt_vertex[q][v][color_set_use][n_del_left];
  1313. if (MODE == DEBUG_MODE) write_log("u = " + my_to_string(u) + "\n");
  1314. int q_nxt = Q_tree.child[q][0];
  1315. if (u == v) {
  1316. trace_result_matching_fd(q_nxt, v, color_set_use, n_del_left - 1);
  1317. }
  1318. else if (u >= 0) {
  1319. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(u)
  1320. + "=" + my_double_to_string(G.get_weight(v, u)));
  1321. trace_result_matching_fm(q_nxt, u, color_set_use, n_del_left - 1);
  1322. }
  1323. else { // u < 0
  1324. if (MODE == DEBUG_MODE) write_log("edge cost = " + my_to_string(v) + "->" + my_to_string(-u-1)
  1325. + "=" + my_double_to_string(G.get_weight(v, -u-1)));
  1326. trace_result_matching_fi(q_nxt, -u - 1, color_set_use, n_del_left - 1);
  1327. }
  1328. if (MODE == DEBUG_MODE) write_log("trace_result_matching_fd(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = "
  1329. + my_to_string(color_set_use) + ", n_del_left = " + my_to_string(n_del_left) + ") done\n");
  1330. }
  1331.  
  1332. void get_result() {
  1333. if (MODE == DEBUG_MODE) write_log("get_result()...\n");
  1334. double this_best_score = -INF;
  1335. int root_map_to = -1, start_color_set = -1, start_n_del_left = -1;
  1336. for(int v = 0; v < G.n; ++v)
  1337. //map Q.root -> v
  1338. for(int color_set_use = 0; color_set_use < (1 << n_colors); ++color_set_use)
  1339. for(int n_del_left = 0; n_del_left <= n_del; ++n_del_left) {
  1340. if ((MODE == DEBUG_MODE) && (!equals(fm[Q_tree.root][v][color_set_use][n_del_left], -INF)))
  1341. write_log("fm(" + my_to_string(Q_tree.root) + "," + my_to_string(v) + "," + my_to_string(color_set_use) + "," +
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:560:9: error: expected unqualified-id before ‘if’
         if (MODE == DEBUG_MODE) write_log("update_fd(q = " + my_to_string(q) + ", v = " + my_to_string(v) + ", color_set_use = " + my_to_string(color_set_use)
         ^~
prog.cpp: In function ‘void update_fd(int)’:
prog.cpp:565:26: error: ‘can_delete’ was not declared in this scope
         if (!can_delete(q)) return;
                          ^
prog.cpp:565:26: note: suggested alternative:
prog.cpp:402:10: note:   ‘tree_match_graph::can_delete’
     bool can_delete(int q) {
          ^~~~~~~~~~
prog.cpp:569:21: error: ‘can_use_color_set’ was not declared in this scope
                 if (can_use_color_set[color_set_use])
                     ^~~~~~~~~~~~~~~~~
prog.cpp:569:21: note: suggested alternative:
prog.cpp:378:18: note:   ‘tree_match_graph::can_use_color_set’
     vector<bool> can_use_color_set;
                  ^~~~~~~~~~~~~~~~~
prog.cpp:571:66: error: too many arguments to function ‘void update_fd(int)’
                         update_fd(q, v, color_set_use, n_del_left);
                                                                  ^
prog.cpp:564:10: note: declared here
     void update_fd(int q) {
          ^~~~~~~~~
prog.cpp: In function ‘void init_dp(int)’:
prog.cpp:581:21: error: ‘fm’ was not declared in this scope
                     fm[q][v][color_set][n_del_left] = -INF;
                     ^~
prog.cpp:581:21: note: suggested alternative:
prog.cpp:372:44: note:   ‘tree_match_graph::fm’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                            ^~
prog.cpp:582:21: error: ‘fi’ was not declared in this scope
                     fi[q][v][color_set][n_del_left] = -INF;
                     ^~
prog.cpp:582:21: note: suggested alternative:
prog.cpp:372:48: note:   ‘tree_match_graph::fi’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                                ^~
prog.cpp:583:21: error: ‘fd’ was not declared in this scope
                     fd[q][v][color_set][n_del_left] = -INF;
                     ^~
prog.cpp:583:21: note: suggested alternative:
prog.cpp:372:52: note:   ‘tree_match_graph::fd’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                                    ^~
prog.cpp:586:46: error: ‘can_map’ was not declared in this scope
             if (can_map(q, (1 << color[v]), v)) {
                                              ^
prog.cpp:586:46: note: suggested alternative:
prog.cpp:395:10: note:   ‘tree_match_graph::can_map’
     bool can_map(int u, int color_set_use, int v) {
          ^~~~~~~
prog.cpp:587:17: error: ‘fm’ was not declared in this scope
                 fm[q][v][add_vertex(0, v)][0] = (match[q] == -1) ? get_similar_score(q, v) : 0.0;
                 ^~
prog.cpp:587:17: note: suggested alternative:
prog.cpp:372:44: note:   ‘tree_match_graph::fm’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                            ^~
prog.cpp:587:41: error: ‘add_vertex’ was not declared in this scope
                 fm[q][v][add_vertex(0, v)][0] = (match[q] == -1) ? get_similar_score(q, v) : 0.0;
                                         ^
prog.cpp:587:41: note: suggested alternative:
prog.cpp:412:9: note:   ‘tree_match_graph::add_vertex’
     int add_vertex(int color_set, int vertex) {
         ^~~~~~~~~~
prog.cpp:587:50: error: ‘match’ was not declared in this scope
                 fm[q][v][add_vertex(0, v)][0] = (match[q] == -1) ? get_similar_score(q, v) : 0.0;
                                                  ^~~~~
prog.cpp:587:50: note: suggested alternative:
prog.cpp:368:17: note:   ‘tree_match_graph::match’
     vector<int> match;
                 ^~~~~
prog.cpp:587:90: error: ‘get_similar_score’ was not declared in this scope
                 fm[q][v][add_vertex(0, v)][0] = (match[q] == -1) ? get_similar_score(q, v) : 0.0;
                                                                                          ^
prog.cpp:587:90: note: suggested alternative:
prog.cpp:385:12: note:   ‘tree_match_graph::get_similar_score’
     double get_similar_score(int q, int v) {
            ^~~~~~~~~~~~~~~~~
prog.cpp: In function ‘void write_log_dp_values(int)’:
prog.cpp:599:33: error: ‘fm’ was not declared in this scope
                     if (!equals(fm[q][v][color_set][n_del_left], -INF))
                                 ^~
prog.cpp:599:33: note: suggested alternative:
prog.cpp:372:44: note:   ‘tree_match_graph::fm’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                            ^~
prog.cpp:606:33: error: ‘fi’ was not declared in this scope
                     if (!equals(fi[q][v][color_set][n_del_left], -INF))
                                 ^~
prog.cpp:606:33: note: suggested alternative:
prog.cpp:372:48: note:   ‘tree_match_graph::fi’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                                ^~
prog.cpp:613:33: error: ‘fd’ was not declared in this scope
                     if (!equals(fd[q][v][color_set][n_del_left], -INF))
                                 ^~
prog.cpp:613:33: note: suggested alternative:
prog.cpp:372:52: note:   ‘tree_match_graph::fd’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                                    ^~
prog.cpp: In function ‘void DFS(int)’:
prog.cpp:625:27: error: ‘update_fm’ was not declared in this scope
             update_fm(u, k);
                           ^
prog.cpp:625:27: note: suggested alternative:
prog.cpp:471:10: note:   ‘tree_match_graph::update_fm’
     void update_fm(int q, int k_th_child) {
          ^~~~~~~~~
prog.cpp:627:20: error: ‘update_fi’ was not declared in this scope
         update_fi(u);
                    ^
prog.cpp:627:20: note: suggested alternative:
prog.cpp:521:10: note:   ‘tree_match_graph::update_fi’
     void update_fi(int q) {
          ^~~~~~~~~
prog.cpp: In function ‘void trace_result_matching_fm(int, int, int, int)’:
prog.cpp:642:78: error: ‘fm’ was not declared in this scope
         if (MODE == DEBUG_MODE) write_log("with fm = " + my_double_to_string(fm[q][v][color_set_use][n_del_left]));
                                                                              ^~
prog.cpp:642:78: note: suggested alternative:
prog.cpp:372:44: note:   ‘tree_match_graph::fm’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                            ^~
prog.cpp:644:113: error: ‘get_similar_score’ was not declared in this scope
                                           + my_to_string(v) + " = " + my_double_to_string(get_similar_score(q, v)) + "\n");
                                                                                                                 ^
prog.cpp:644:113: note: suggested alternative:
prog.cpp:385:12: note:   ‘tree_match_graph::get_similar_score’
     double get_similar_score(int q, int v) {
            ^~~~~~~~~~~~~~~~~
prog.cpp:648:21: error: ‘trace_fm_nxt_vertex’ was not declared in this scope
             int u = trace_fm_nxt_vertex[q][k_th_child][v][color_set_use][n_del_left];
                     ^~~~~~~~~~~~~~~~~~~
prog.cpp:648:21: note: suggested alternative:
prog.cpp:374:86: note:   ‘tree_match_graph::trace_fm_nxt_vertex’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                                                      ^~~~~~~~~~~~~~~~~~~
prog.cpp:652:52: error: ‘trace_fm_color’ was not declared in this scope
                 trace_result_matching_fd(child, v, trace_fm_color[q][k_th_child][v][color_set_use][n_del_left],
                                                    ^~~~~~~~~~~~~~
prog.cpp:652:52: note: suggested alternative:
prog.cpp:374:49: note:   ‘tree_match_graph::trace_fm_color’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                 ^~~~~~~~~~~~~~
prog.cpp:653:42: error: ‘trace_fm_n_del_left’ was not declared in this scope
                                          trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left]);
                                          ^~~~~~~~~~~~~~~~~~~
prog.cpp:653:42: note: suggested alternative:
prog.cpp:374:65: note:   ‘tree_match_graph::trace_fm_n_del_left’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                                 ^~~~~~~~~~~~~~~~~~~
prog.cpp:658:52: error: ‘trace_fm_color’ was not declared in this scope
                 trace_result_matching_fm(child, u, trace_fm_color[q][k_th_child][v][color_set_use][n_del_left],
                                                    ^~~~~~~~~~~~~~
prog.cpp:658:52: note: suggested alternative:
prog.cpp:374:49: note:   ‘tree_match_graph::trace_fm_color’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                 ^~~~~~~~~~~~~~
prog.cpp:659:42: error: ‘trace_fm_n_del_left’ was not declared in this scope
                                          trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left]);
                                          ^~~~~~~~~~~~~~~~~~~
prog.cpp:659:42: note: suggested alternative:
prog.cpp:374:65: note:   ‘tree_match_graph::trace_fm_n_del_left’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                                 ^~~~~~~~~~~~~~~~~~~
prog.cpp:664:57: error: ‘trace_fm_color’ was not declared in this scope
                 trace_result_matching_fi(child, -u - 1, trace_fm_color[q][k_th_child][v][color_set_use][n_del_left],
                                                         ^~~~~~~~~~~~~~
prog.cpp:664:57: note: suggested alternative:
prog.cpp:374:49: note:   ‘tree_match_graph::trace_fm_color’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                 ^~~~~~~~~~~~~~
prog.cpp:665:42: error: ‘trace_fm_n_del_left’ was not declared in this scope
                                          trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left]);
                                          ^~~~~~~~~~~~~~~~~~~
prog.cpp:665:42: note: suggested alternative:
prog.cpp:374:65: note:   ‘tree_match_graph::trace_fm_n_del_left’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                                 ^~~~~~~~~~~~~~~~~~~
prog.cpp:667:49: error: ‘trace_fm_color’ was not declared in this scope
             int nxt_color_set = color_set_use - trace_fm_color[q][k_th_child][v][color_set_use][n_del_left];
                                                 ^~~~~~~~~~~~~~
prog.cpp:667:49: note: suggested alternative:
prog.cpp:374:49: note:   ‘tree_match_graph::trace_fm_color’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                 ^~~~~~~~~~~~~~
prog.cpp:668:47: error: ‘trace_fm_n_del_left’ was not declared in this scope
             int nxt_n_del_left = n_del_left - trace_fm_n_del_left[q][k_th_child][v][color_set_use][n_del_left];
                                               ^~~~~~~~~~~~~~~~~~~
prog.cpp:668:47: note: suggested alternative:
prog.cpp:374:65: note:   ‘tree_match_graph::trace_fm_n_del_left’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                                 ^~~~~~~~~~~~~~~~~~~
prog.cpp: In function ‘void trace_result_matching_fi(int, int, int, int)’:
prog.cpp:680:78: error: ‘fi’ was not declared in this scope
         if (MODE == DEBUG_MODE) write_log("with fi = " + my_double_to_string(fi[q][v][color_set_use][n_del_left]));
                                                                              ^~
prog.cpp:680:78: note: suggested alternative:
prog.cpp:372:48: note:   ‘tree_match_graph::fi’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                                ^~
prog.cpp:682:17: error: ‘trace_fi_nxt_vertex’ was not declared in this scope
         int u = trace_fi_nxt_vertex[q][v][color_set_use][n_del_left];
                 ^~~~~~~~~~~~~~~~~~~
prog.cpp:682:17: note: suggested alternative:
prog.cpp:375:41: note:   ‘tree_match_graph::trace_fi_nxt_vertex’
     vector<vector<vector<vector<int>>>> trace_fi_nxt_vertex, trace_fd_nxt_vertex;
                                         ^~~~~~~~~~~~~~~~~~~
prog.cpp: In function ‘void trace_result_matching_fd(int, int, int, int)’:
prog.cpp:701:78: error: ‘fd’ was not declared in this scope
         if (MODE == DEBUG_MODE) write_log("with fd = " + my_double_to_string(fd[q][v][color_set_use][n_del_left]));
                                                                              ^~
prog.cpp:701:78: note: suggested alternative:
prog.cpp:372:52: note:   ‘tree_match_graph::fd’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                                    ^~
prog.cpp:702:17: error: ‘trace_fd_nxt_vertex’ was not declared in this scope
         int u = trace_fd_nxt_vertex[q][v][color_set_use][n_del_left];
                 ^~~~~~~~~~~~~~~~~~~
prog.cpp:702:17: note: suggested alternative:
prog.cpp:375:62: note:   ‘tree_match_graph::trace_fd_nxt_vertex’
     vector<vector<vector<vector<int>>>> trace_fi_nxt_vertex, trace_fd_nxt_vertex;
                                                              ^~~~~~~~~~~~~~~~~~~
prog.cpp: In function ‘void get_result()’:
prog.cpp:730:58: error: ‘fm’ was not declared in this scope
                     if ((MODE == DEBUG_MODE) && (!equals(fm[Q_tree.root][v][color_set_use][n_del_left], -INF)))
                                                          ^~
prog.cpp:730:58: note: suggested alternative:
prog.cpp:372:44: note:   ‘tree_match_graph::fm’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                            ^~
prog.cpp:732:51: error: ‘fm’ was not declared in this scope
                     if (maximize(this_best_score, fm[Q_tree.root][v][color_set_use][n_del_left])) {
                                                   ^~
prog.cpp:732:51: note: suggested alternative:
prog.cpp:372:44: note:   ‘tree_match_graph::fm’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                            ^~
prog.cpp:738:64: error: ‘pre_assign_score’ was not declared in this scope
         if (!equals(this_best_score, -INF)) this_best_score += pre_assign_score;
                                                                ^~~~~~~~~~~~~~~~
prog.cpp:738:64: note: suggested alternative:
prog.cpp:379:12: note:   ‘tree_match_graph::pre_assign_score’
     double pre_assign_score;
            ^~~~~~~~~~~~~~~~
prog.cpp:741:17: error: ‘best_root_map_to’ was not declared in this scope
                 best_root_map_to = root_map_to;
                 ^~~~~~~~~~~~~~~~
prog.cpp:741:17: note: suggested alternative:
prog.cpp:370:9: note:   ‘tree_match_graph::best_root_map_to’
     int best_root_map_to, best_color_set, best_n_del_left;
         ^~~~~~~~~~~~~~~~
prog.cpp:742:17: error: ‘best_color_set’ was not declared in this scope
                 best_color_set = start_color_set;
                 ^~~~~~~~~~~~~~
prog.cpp:742:17: note: suggested alternative:
prog.cpp:370:27: note:   ‘tree_match_graph::best_color_set’
     int best_root_map_to, best_color_set, best_n_del_left;
                           ^~~~~~~~~~~~~~
prog.cpp:743:17: error: ‘best_n_del_left’ was not declared in this scope
                 best_n_del_left = start_n_del_left;
                 ^~~~~~~~~~~~~~~
prog.cpp:743:17: note: suggested alternative:
prog.cpp:370:43: note:   ‘tree_match_graph::best_n_del_left’
     int best_root_map_to, best_color_set, best_n_del_left;
                                           ^~~~~~~~~~~~~~~
prog.cpp:745:21: error: ‘best_coloring’ was not declared in this scope
                     best_coloring[v] = color[v];
                     ^~~~~~~~~~~~~
prog.cpp:745:21: note: suggested alternative:
prog.cpp:371:17: note:   ‘tree_match_graph::best_coloring’
     vector<int> best_coloring;
                 ^~~~~~~~~~~~~
prog.cpp:746:21: error: ‘best_choosed’ was not declared in this scope
                     best_choosed[v] = choosed[v];
                     ^~~~~~~~~~~~
prog.cpp:746:21: note: suggested alternative:
prog.cpp:377:26: note:   ‘tree_match_graph::best_choosed’
     vector<int> choosed, best_choosed;
                          ^~~~~~~~~~~~
prog.cpp:746:39: error: ‘choosed’ was not declared in this scope
                     best_choosed[v] = choosed[v];
                                       ^~~~~~~
prog.cpp:746:39: note: suggested alternative:
prog.cpp:377:17: note:   ‘tree_match_graph::choosed’
     vector<int> choosed, best_choosed;
                 ^~~~~~~
prog.cpp: In function ‘void init_before_dp_on_tree()’:
prog.cpp:765:9: error: ‘can_use_color_set’ was not declared in this scope
         can_use_color_set.resize((1 << n_colors));
         ^~~~~~~~~~~~~~~~~
prog.cpp:765:9: note: suggested alternative:
prog.cpp:378:18: note:   ‘tree_match_graph::can_use_color_set’
     vector<bool> can_use_color_set;
                  ^~~~~~~~~~~~~~~~~
prog.cpp:769:21: error: ‘choosed’ was not declared in this scope
                 if (choosed[v] != -1)
                     ^~~~~~~
prog.cpp:769:21: note: suggested alternative:
prog.cpp:377:17: note:   ‘tree_match_graph::choosed’
     vector<int> choosed, best_choosed;
                 ^~~~~~~
prog.cpp:774:9: error: ‘pre_assign_score’ was not declared in this scope
         pre_assign_score = 0.0;
         ^~~~~~~~~~~~~~~~
prog.cpp:774:9: note: suggested alternative:
prog.cpp:379:12: note:   ‘tree_match_graph::pre_assign_score’
     double pre_assign_score;
            ^~~~~~~~~~~~~~~~
prog.cpp:776:17: error: ‘match’ was not declared in this scope
             if (match[q] != -1)
                 ^~~~~
prog.cpp:776:17: note: suggested alternative:
prog.cpp:368:17: note:   ‘tree_match_graph::match’
     vector<int> match;
                 ^~~~~
prog.cpp:777:66: error: ‘get_similar_score’ was not declared in this scope
                 pre_assign_score += get_similar_score(q, match[q]);
                                                                  ^
prog.cpp:777:66: note: suggested alternative:
prog.cpp:385:12: note:   ‘tree_match_graph::get_similar_score’
     double get_similar_score(int q, int v) {
            ^~~~~~~~~~~~~~~~~
prog.cpp: In function ‘void dp_on_tree()’:
prog.cpp:785:17: error: ‘match’ was not declared in this scope
             if (match[i] != -1) cout << i << "->" << match[i] << endl;
                 ^~~~~
prog.cpp:785:17: note: suggested alternative:
prog.cpp:368:17: note:   ‘tree_match_graph::match’
     vector<int> match;
                 ^~~~~
prog.cpp: In function ‘void backtrack_assign(int, int)’:
prog.cpp:803:18: error: ‘choosed’ was not declared in this scope
             if ((choosed[v] == -1) && (get_bit(set_choosed, color[v]) == 0) && (G.get_deg(v) >= Q_graph.get_deg(qi) - n_del)) {
                  ^~~~~~~
prog.cpp:803:18: note: suggested alternative:
prog.cpp:377:17: note:   ‘tree_match_graph::choosed’
     vector<int> choosed, best_choosed;
                 ^~~~~~~
prog.cpp:805:17: error: ‘match’ was not declared in this scope
                 match[q] = v;
                 ^~~~~
prog.cpp:805:17: note: suggested alternative:
prog.cpp:368:17: note:   ‘tree_match_graph::match’
     vector<int> match;
                 ^~~~~
prog.cpp: In function ‘void pre_assignment()’:
prog.cpp:813:9: error: ‘choosed’ was not declared in this scope
         choosed.resize(G.n); best_choosed.resize(G.n);
         ^~~~~~~
prog.cpp:813:9: note: suggested alternative:
prog.cpp:377:17: note:   ‘tree_match_graph::choosed’
     vector<int> choosed, best_choosed;
                 ^~~~~~~
prog.cpp:813:30: error: ‘best_choosed’ was not declared in this scope
         choosed.resize(G.n); best_choosed.resize(G.n);
                              ^~~~~~~~~~~~
prog.cpp:813:30: note: suggested alternative:
prog.cpp:377:26: note:   ‘tree_match_graph::best_choosed’
     vector<int> choosed, best_choosed;
                          ^~~~~~~~~~~~
prog.cpp:815:9: error: ‘match’ was not declared in this scope
         match.resize(Q_graph.n);
         ^~~~~
prog.cpp:815:9: note: suggested alternative:
prog.cpp:368:17: note:   ‘tree_match_graph::match’
     vector<int> match;
                 ^~~~~
prog.cpp: In function ‘void init_trace_best_matching()’:
prog.cpp:828:49: error: ‘best_coloring’ was not declared in this scope
         for(int v = 0; v < G.n; ++v) color[v] = best_coloring[v];
                                                 ^~~~~~~~~~~~~
prog.cpp:828:49: note: suggested alternative:
prog.cpp:371:17: note:   ‘tree_match_graph::best_coloring’
     vector<int> best_coloring;
                 ^~~~~~~~~~~~~
prog.cpp:829:9: error: ‘choosed’ was not declared in this scope
         choosed = best_choosed;
         ^~~~~~~
prog.cpp:829:9: note: suggested alternative:
prog.cpp:377:17: note:   ‘tree_match_graph::choosed’
     vector<int> choosed, best_choosed;
                 ^~~~~~~
prog.cpp:829:19: error: ‘best_choosed’ was not declared in this scope
         choosed = best_choosed;
                   ^~~~~~~~~~~~
prog.cpp:829:19: note: suggested alternative:
prog.cpp:377:26: note:   ‘tree_match_graph::best_choosed’
     vector<int> choosed, best_choosed;
                          ^~~~~~~~~~~~
prog.cpp:831:13: error: ‘match’ was not declared in this scope
             match[q] = -1;
             ^~~~~
prog.cpp:831:13: note: suggested alternative:
prog.cpp:368:17: note:   ‘tree_match_graph::match’
     vector<int> match;
                 ^~~~~
prog.cpp:834:17: error: ‘match’ was not declared in this scope
                 match[choosed[v]] = v;
                 ^~~~~
prog.cpp:834:17: note: suggested alternative:
prog.cpp:368:17: note:   ‘tree_match_graph::match’
     vector<int> match;
                 ^~~~~
prog.cpp: In function ‘void trace_best_matching()’:
prog.cpp:855:47: error: ‘best_root_map_to’ was not declared in this scope
         trace_result_matching_fm(Q_tree.root, best_root_map_to, best_color_set, best_n_del_left);
                                               ^~~~~~~~~~~~~~~~
prog.cpp:855:47: note: suggested alternative:
prog.cpp:370:9: note:   ‘tree_match_graph::best_root_map_to’
     int best_root_map_to, best_color_set, best_n_del_left;
         ^~~~~~~~~~~~~~~~
prog.cpp:855:65: error: ‘best_color_set’ was not declared in this scope
         trace_result_matching_fm(Q_tree.root, best_root_map_to, best_color_set, best_n_del_left);
                                                                 ^~~~~~~~~~~~~~
prog.cpp:855:65: note: suggested alternative:
prog.cpp:370:27: note:   ‘tree_match_graph::best_color_set’
     int best_root_map_to, best_color_set, best_n_del_left;
                           ^~~~~~~~~~~~~~
prog.cpp:855:81: error: ‘best_n_del_left’ was not declared in this scope
         trace_result_matching_fm(Q_tree.root, best_root_map_to, best_color_set, best_n_del_left);
                                                                                 ^~~~~~~~~~~~~~~
prog.cpp:855:81: note: suggested alternative:
prog.cpp:370:43: note:   ‘tree_match_graph::best_n_del_left’
     int best_root_map_to, best_color_set, best_n_del_left;
                                           ^~~~~~~~~~~~~~~
prog.cpp: In function ‘void init_vector_dimension()’:
prog.cpp:933:21: error: ‘fm’ was not declared in this scope
         init_vector(fm, Q_tree.n, G.n, (1 << n_colors), n_del + 1, -INF);
                     ^~
prog.cpp:933:21: note: suggested alternative:
prog.cpp:372:44: note:   ‘tree_match_graph::fm’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                            ^~
prog.cpp:934:21: error: ‘fi’ was not declared in this scope
         init_vector(fi, Q_tree.n, G.n, (1 << n_colors), n_del + 1, -INF);
                     ^~
prog.cpp:934:21: note: suggested alternative:
prog.cpp:372:48: note:   ‘tree_match_graph::fi’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                                ^~
prog.cpp:935:21: error: ‘fd’ was not declared in this scope
         init_vector(fd, Q_tree.n, G.n, (1 << n_colors), n_del + 1, -INF);
                     ^~
prog.cpp:935:21: note: suggested alternative:
prog.cpp:372:52: note:   ‘tree_match_graph::fd’
     vector<vector<vector<vector<double>>>> fm, fi, fd; //f(u, v, color_set_use, num_deletion_left)
                                                    ^~
prog.cpp:937:21: error: ‘fm_temp’ was not declared in this scope
         init_vector(fm_temp, G.n, (1 << n_colors), n_del + 1, -INF);
                     ^~~~~~~
prog.cpp:937:21: note: suggested alternative:
prog.cpp:373:36: note:   ‘tree_match_graph::fm_temp’
     vector<vector<vector<double>>> fm_temp;
                                    ^~~~~~~
prog.cpp:939:9: error: ‘trace_fm_color’ was not declared in this scope
         trace_fm_color.resize(Q_tree.n);
         ^~~~~~~~~~~~~~
prog.cpp:939:9: note: suggested alternative:
prog.cpp:374:49: note:   ‘tree_match_graph::trace_fm_color’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                 ^~~~~~~~~~~~~~
prog.cpp:940:9: error: ‘trace_fm_n_del_left’ was not declared in this scope
         trace_fm_n_del_left.resize(Q_tree.n);
         ^~~~~~~~~~~~~~~~~~~
prog.cpp:940:9: note: suggested alternative:
prog.cpp:374:65: note:   ‘tree_match_graph::trace_fm_n_del_left’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                                 ^~~~~~~~~~~~~~~~~~~
prog.cpp:941:9: error: ‘trace_fm_nxt_vertex’ was not declared in this scope
         trace_fm_nxt_vertex.resize(Q_tree.n);
         ^~~~~~~~~~~~~~~~~~~
prog.cpp:941:9: note: suggested alternative:
prog.cpp:374:86: note:   ‘tree_match_graph::trace_fm_nxt_vertex’
     vector<vector<vector<vector<vector<int>>>>> trace_fm_color, trace_fm_n_del_left, trace_fm_nxt_vertex;
                                                                                      ^~~~~~~~~~~~~~~~~~~
prog.cpp:943:21: error: ‘trace_fi_nxt_vertex’ was not declared in this scope
         init_vector(trace_fi_nxt_vertex, Q_tree.n, G.n, (1 << n_colors), n_del + 1, -1);
                     ^~~~~~~~~~~~~~~~~~~
prog.cpp:943:21: note: suggested alternative:
prog.cpp:375:41: note:   ‘tree_match_graph::trace_fi_nxt_vertex’
     vector<vector<vector<vector<int>>>> trace_fi_nxt_vertex, trace_fd_nxt_vertex;
                                         ^~~~~~~~~~~~~~~~~~~
prog.cpp:944:21: error: ‘trace_fd_nxt_vertex’ was not declared in this scope
         init_vector(trace_fd_nxt_vertex, Q_tree.n, G.n, (1 << n_colors), n_del + 1, -1);
                     ^~~~~~~~~~~~~~~~~~~
prog.cpp:944:21: note: suggested alternative:
prog.cpp:375:62: note:   ‘tree_match_graph::trace_fd_nxt_vertex’
     vector<vector<vector<vector<int>>>> trace_fi_nxt_vertex, trace_fd_nxt_vertex;
                                                              ^~~~~~~~~~~~~~~~~~~
prog.cpp: In function ‘void solve()’:
prog.cpp:959:9: error: ‘best_coloring’ was not declared in this scope
         best_coloring.resize(G.n);
         ^~~~~~~~~~~~~
prog.cpp:959:9: note: suggested alternative:
prog.cpp:371:17: note:   ‘tree_match_graph::best_coloring’
     vector<int> best_coloring;
                 ^~~~~~~~~~~~~
prog.cpp: At global scope:
prog.cpp:973:1: error: expected declaration before ‘}’ token
 }
 ^
stdout
Standard output is empty