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