53  optimal_solution_found_ = 
false;
 
   66  int64_t overflow_detection = 
CapAdd(maximum_edge_cost_, maximum_edge_cost_);
 
   71  const int num_nodes = matches_.size();
 
   73  VLOG(2) << graph_->DebugString();
 
   74  VLOG(1) << 
"num_unmatched: " << num_nodes - graph_->NumMatched()
 
   75          << 
" dual_objective: " << graph_->DualObjective();
 
   77  while (graph_->NumMatched() != num_nodes) {
 
   78    graph_->PrimalUpdates();
 
   80      graph_->DebugCheckNoPossiblePrimalUpdates();
 
   83    VLOG(1) << 
"num_unmatched: " << num_nodes - graph_->NumMatched()
 
   84            << 
" dual_objective: " << graph_->DualObjective();
 
   85    if (graph_->NumMatched() == num_nodes) 
break;
 
   87    const BlossomGraph::CostValue delta =
 
   88        graph_->ComputeMaxCommonTreeDualDeltaAndResetPrimalEdgeQueue();
 
   89    overflow_detection = 
CapAdd(overflow_detection, std::abs(delta.value()));
 
   94    if (delta == 0) 
break;  
 
   95    graph_->UpdateAllTrees(delta);
 
   98  VLOG(1) << 
"End: " << graph_->NumMatched() << 
" / " << num_nodes;
 
   99  graph_->DisplayStats();
 
  100  if (graph_->NumMatched() < num_nodes) {
 
  103  VLOG(2) << graph_->DebugString();
 
  104  CHECK(graph_->DebugDualsAreFeasible());
 
  108  graph_->ExpandAllBlossoms();
 
  109  for (
int i = 0; i < num_nodes; ++i) {
 
  110    matches_[i] = graph_->Match(BlossomGraph::NodeIndex(i)).value();
 
  113  optimal_solution_found_ = 
true;
 
  114  optimal_cost_ = graph_->DualObjective().value();
 
  115  if (optimal_cost_ == std::numeric_limits<int64_t>::max())
 
 
  158  CHECK(!is_initialized_);
 
  159  is_initialized_ = 
true;
 
  161  for (
NodeIndex n(0); n < nodes_.size(); ++n) {
 
  162    if (graph_[n].empty()) 
return false;  
 
  169    for (
const EdgeIndex e : graph_[n]) {
 
  170      min_cost = std::min(min_cost, edges_[e].pseudo_slack);
 
  173    nodes_[n].pseudo_dual = min_cost / 2;
 
  181  for (EdgeIndex e(0); e < edges_.size(); ++e) {
 
  182    Edge& mutable_edge = edges_[e];
 
  184                                 nodes_[mutable_edge.
head].pseudo_dual;
 
  188  for (
NodeIndex n(0); n < nodes_.size(); ++n) {
 
  194    for (
const EdgeIndex e : graph_[n]) {
 
  195      min_slack = std::min(min_slack, edges_[e].pseudo_slack);
 
  199      nodes_[n].pseudo_dual += min_slack;
 
  200      for (
const EdgeIndex e : graph_[n]) {
 
  201        edges_[e].pseudo_slack -= min_slack;
 
  209    for (
const EdgeIndex e : graph_[n]) {
 
  210      const Edge& edge = edges_[e];
 
  213        nodes_[edge.
tail].type = 0;
 
  214        nodes_[edge.
tail].match = edge.
head;
 
  215        nodes_[edge.
head].type = 0;
 
  216        nodes_[edge.
head].match = edge.
tail;
 
  223  for (
NodeIndex n(0); n < nodes_.size(); ++n) {
 
  225    unmatched_nodes_.push_back(n);
 
  236  for (
NodeIndex n(0); n < nodes_.size(); ++n) {
 
  238    nodes_[n].pseudo_dual *= 2;
 
  239    AddToDualObjective(nodes_[n].pseudo_dual);
 
  241    nodes_[n].dual = nodes_[n].pseudo_dual;
 
  244  for (EdgeIndex e(0); e < edges_.size(); ++e) {
 
  246    edges_[e].pseudo_slack *= 2;
 
  248    edges_[e].slack = edges_[e].pseudo_slack;
 
  254  if (!unmatched_nodes_.empty()) {
 
  255    primal_update_edge_queue_.clear();
 
  256    for (EdgeIndex e(0); e < edges_.size(); ++e) {
 
  257      Edge& edge = edges_[e];
 
  258      const bool tail_is_plus = nodes_[edge.
tail].IsPlus();
 
  259      const bool head_is_plus = nodes_[edge.
head].IsPlus();
 
  260      if (tail_is_plus && head_is_plus) {
 
  261        plus_plus_pq_.Add(&edge);
 
  262        if (edge.
pseudo_slack == 0) primal_update_edge_queue_.push_back(e);
 
  263      } 
else if (tail_is_plus || head_is_plus) {
 
  264        plus_free_pq_.Add(&edge);
 
  265        if (edge.
pseudo_slack == 0) primal_update_edge_queue_.push_back(e);
 
 
  276  for (
NodeIndex n(0); n < nodes_.size(); ++n) {
 
  277    const Node& node = nodes_[n];
 
  279      best_update = std::min(best_update, 
Dual(node));
 
  284  CHECK(!unmatched_nodes_.empty());
 
  285  const CostValue tree_delta = nodes_[unmatched_nodes_.front()].tree_dual_delta;
 
  287  if (!plus_plus_pq_.IsEmpty()) {
 
  288    DCHECK_EQ(plus_plus_pq_.Top()->pseudo_slack % 2, 0) << 
"Non integer bound!";
 
  289    plus_plus_slack = plus_plus_pq_.Top()->pseudo_slack / 2 - tree_delta;
 
  290    best_update = std::min(best_update, plus_plus_slack);
 
  293  if (!plus_free_pq_.IsEmpty()) {
 
  294    plus_free_slack = plus_free_pq_.Top()->pseudo_slack - tree_delta;
 
  295    best_update = std::min(best_update, plus_free_slack);
 
  306  primal_update_edge_queue_.clear();
 
  307  if (plus_plus_slack == best_update) {
 
  308    plus_plus_pq_.AllTop(&tmp_all_tops_);
 
  309    for (
const Edge* pt : tmp_all_tops_) {
 
  310      primal_update_edge_queue_.push_back(EdgeIndex(pt - &edges_.front()));
 
  313  if (plus_free_slack == best_update) {
 
  314    plus_free_pq_.AllTop(&tmp_all_tops_);
 
  315    for (
const Edge* pt : tmp_all_tops_) {
 
  316      primal_update_edge_queue_.push_back(EdgeIndex(pt - &edges_.front()));
 
 
  401    possible_shrink_.clear();
 
  404    while (!primal_update_edge_queue_.empty()) {
 
  405      const EdgeIndex e = primal_update_edge_queue_.back();
 
  406      primal_update_edge_queue_.pop_back();
 
  412      const Edge& edge = edges_[e];
 
  413      if (
Slack(edge) != 0) 
continue;
 
  417      if (!nodes_[tail].IsPlus()) std::swap(tail, head);
 
  418      if (!nodes_[tail].IsPlus()) 
continue;
 
  420      if (nodes_[head].IsFree()) {
 
  422      } 
else if (nodes_[head].IsPlus()) {
 
  423        if (nodes_[tail].root != nodes_[head].root) {
 
  426          possible_shrink_.push_back(e);
 
  432    for (
const EdgeIndex e : possible_shrink_) {
 
  433      const Edge& edge = edges_[e];
 
  436      const Node& tail_node = nodes_[tail];
 
  437      const Node& head_node = nodes_[head];
 
  439          tail_node.
root == head_node.
root && tail != head) {
 
  445    if (!primal_update_edge_queue_.empty()) 
continue;
 
  453    for (
NodeIndex n(0); n < nodes_.size(); ++n) {
 
  454      const Node& node = nodes_[n];
 
  460    if (num_expands == 0) 
break;
 
 
  486  VLOG(2) << 
"Grow " << tail << 
" -> " << head << 
" === " << 
Match(head);
 
  489  DCHECK(nodes_[tail].IsPlus());
 
  490  DCHECK(nodes_[head].IsFree());
 
  493  const NodeIndex root = nodes_[tail].root;
 
  496  Node& head_node = nodes_[head];
 
  497  head_node.
root = root;
 
  502  const CostValue tree_dual = nodes_[root].tree_dual_delta;
 
  504  for (
const NodeIndex subnode : SubNodes(head)) {
 
  505    for (
const EdgeIndex e : graph_[subnode]) {
 
  506      Edge& edge = edges_[e];
 
  507      const NodeIndex other_end = OtherEnd(edge, subnode);
 
  508      if (other_end == head) 
continue;
 
  510      if (plus_free_pq_.Contains(&edge)) plus_free_pq_.Remove(&edge);
 
  514  Node& leaf_node = nodes_[leaf];
 
  515  leaf_node.
root = root;
 
  521  for (
const NodeIndex subnode : SubNodes(leaf)) {
 
  522    for (
const EdgeIndex e : graph_[subnode]) {
 
  523      Edge& edge = edges_[e];
 
  524      const NodeIndex other_end = OtherEnd(edge, subnode);
 
  525      if (other_end == leaf) 
continue;
 
  527      const Node& other_node = nodes_[other_end];
 
  528      if (other_node.
IsPlus()) {
 
  530        DCHECK(plus_free_pq_.Contains(&edge));
 
  531        DCHECK(!plus_plus_pq_.Contains(&edge));
 
  532        plus_free_pq_.Remove(&edge);
 
  533        plus_plus_pq_.Add(&edge);
 
  535          DCHECK_EQ(
Slack(edge), 0);
 
  536          primal_update_edge_queue_.push_back(e);
 
  538      } 
else if (other_node.
IsFree()) {
 
  540        DCHECK(!plus_free_pq_.Contains(&edge));
 
  541        DCHECK(!plus_plus_pq_.Contains(&edge));
 
  542        plus_free_pq_.Add(&edge);
 
  544          DCHECK_EQ(
Slack(edge), 0);
 
  545          primal_update_edge_queue_.push_back(e);
 
 
  564  const Edge& edge = edges_[e];
 
  565  VLOG(2) << 
"Augment " << Tail(edge) << 
" -> " << Head(edge);
 
  567  DCHECK(nodes_[Tail(edge)].IsPlus());
 
  568  DCHECK(nodes_[Head(edge)].IsPlus());
 
  570  const NodeIndex root_a = nodes_[Tail(edge)].root;
 
  571  const NodeIndex root_b = nodes_[Head(edge)].root;
 
  572  DCHECK_NE(root_a, root_b);
 
  575  std::vector<NodeIndex> node_path;
 
  576  AppendNodePathToRoot(Tail(edge), &node_path);
 
  577  std::reverse(node_path.begin(), node_path.end());
 
  578  AppendNodePathToRoot(Head(edge), &node_path);
 
  581  const CostValue delta_a = nodes_[root_a].tree_dual_delta;
 
  582  const CostValue delta_b = nodes_[root_b].tree_dual_delta;
 
  583  nodes_[root_a].tree_dual_delta = 0;
 
  584  nodes_[root_b].tree_dual_delta = 0;
 
  597  for (
NodeIndex n(0); n < nodes_.size(); ++n) {
 
  598    Node& node = nodes_[n];
 
  601    if (root != root_a && root != root_b) 
continue;
 
  603    const CostValue delta = node.
type * (root == root_a ? delta_a : delta_b);
 
  605    for (
const NodeIndex subnode : SubNodes(n)) {
 
  606      for (
const EdgeIndex e : graph_[subnode]) {
 
  607        Edge& edge = edges_[e];
 
  608        const NodeIndex other_end = OtherEnd(edge, subnode);
 
  609        if (other_end == n) 
continue;
 
  615        const Node& other_node = nodes_[other_end];
 
  616        if (other_node.
root != root_a && other_node.
root != root_b &&
 
  618          if (plus_plus_pq_.Contains(&edge)) plus_plus_pq_.Remove(&edge);
 
  619          DCHECK(!plus_free_pq_.Contains(&edge));
 
  620          plus_free_pq_.Add(&edge);
 
  621          if (
Slack(edge) == 0) primal_update_edge_queue_.push_back(e);
 
  623          if (plus_plus_pq_.Contains(&edge)) plus_plus_pq_.Remove(&edge);
 
  624          if (plus_free_pq_.Contains(&edge)) plus_free_pq_.Remove(&edge);
 
  634  CHECK_EQ(node_path.size() % 2, 0);
 
  635  for (
int i = 0; i < node_path.size(); i += 2) {
 
  636    nodes_[node_path[i]].match = node_path[i + 1];
 
  637    nodes_[node_path[i + 1]].match = node_path[i];
 
  646  for (
const NodeIndex n : unmatched_nodes_) {
 
  649  CHECK_EQ(unmatched_nodes_.size(), new_size + 2);
 
  650  unmatched_nodes_.resize(new_size);
 
 
  667  const Edge& edge = edges_[e];
 
  669  DCHECK(nodes_[Tail(edge)].IsPlus());
 
  670  DCHECK(nodes_[Head(edge)].IsPlus());
 
  671  DCHECK_EQ(nodes_[Tail(edge)].root, nodes_[Head(edge)].root);
 
  673  CHECK_NE(Tail(edge), Head(edge)) << e;
 
  678  std::vector<NodeIndex> tail_path;
 
  679  std::vector<NodeIndex> head_path;
 
  683    int tail_depth = GetDepth(tail);
 
  684    int head_depth = GetDepth(head);
 
  685    if (tail_depth > head_depth) {
 
  686      std::swap(tail, head);
 
  687      std::swap(tail_depth, head_depth);
 
  689    VLOG(2) << 
"Shrink " << tail << 
" <-> " << head;
 
  691    while (head_depth > tail_depth) {
 
  692      head_path.push_back(head);
 
  693      head = nodes_[head].parent;
 
  696    while (tail != head) {
 
  697      DCHECK_EQ(tail_depth, head_depth);
 
  698      DCHECK_GE(tail_depth, 0);
 
  704      tail_path.push_back(tail);
 
  705      tail = nodes_[tail].parent;
 
  707      head_path.push_back(head);
 
  708      head = nodes_[head].parent;
 
  711    VLOG(2) << 
"LCA " << lca_index;
 
  713  Node& lca = nodes_[lca_index];
 
  717  std::vector<NodeIndex> blossom = {lca_index};
 
  718  std::reverse(head_path.begin(), head_path.end());
 
  719  blossom.insert(blossom.end(), head_path.begin(), head_path.end());
 
  720  blossom.insert(blossom.end(), tail_path.begin(), tail_path.end());
 
  721  CHECK_EQ(blossom.size() % 2, 1);
 
  723  const CostValue tree_dual = nodes_[lca.
root].tree_dual_delta;
 
  726  CHECK_GT(blossom.size(), 1);
 
  727  Node& backup_node = nodes_[blossom[1]];
 
  738  CHECK_EQ(
Dual(lca), 0);
 
  745    if (n != lca_index) {
 
  746      nodes_[n].is_internal = 
true;
 
  752    Node& mutable_node = nodes_[n];
 
  753    const bool was_minus = mutable_node.
IsMinus();
 
  755        mutable_node.
IsMinus() ? tree_dual : -tree_dual;
 
  756    if (n != lca_index) {
 
  761      mutable_node.
type = 0;
 
  763    for (
const NodeIndex subnode : SubNodes(n)) {
 
  767      root_blossom_node_[subnode] = lca_index;
 
  769      for (
const EdgeIndex e : graph_[subnode]) {
 
  770        Edge& edge = edges_[e];
 
  771        const NodeIndex other_end = OtherEnd(edge, subnode);
 
  774        if (other_end == n) 
continue;
 
  778        if (other_end == lca_index) {
 
  791        Node& mutable_other_node = nodes_[other_end];
 
  793          DCHECK(!plus_free_pq_.Contains(&edge));
 
  794          if (plus_plus_pq_.Contains(&edge)) plus_plus_pq_.Remove(&edge);
 
  797              mutable_other_node.
IsMinus() ? tree_dual : -tree_dual;
 
  802        if (mutable_other_node.
parent == n) {
 
  803          mutable_other_node.
parent = lca_index;
 
  813          DCHECK(!plus_plus_pq_.Contains(&edge));
 
  814          DCHECK(!plus_free_pq_.Contains(&edge));
 
  815          if (mutable_other_node.
IsPlus()) {
 
  816            plus_plus_pq_.Add(&edge);
 
  818              primal_update_edge_queue_.push_back(e);
 
  820          } 
else if (mutable_other_node.
IsFree()) {
 
  821            plus_free_pq_.Add(&edge);
 
  823              primal_update_edge_queue_.push_back(e);
 
  837  lca.
blossom = std::move(blossom);
 
 
  861  VLOG(2) << 
"Expand " << to_expand;
 
  863  Node& node_to_expand = nodes_[to_expand];
 
  865  DCHECK(node_to_expand.
IsMinus());
 
  866  DCHECK_EQ(
Dual(node_to_expand), 0);
 
  868  const EdgeIndex match_edge_index =
 
  869      FindTightExternalEdgeBetweenNodes(to_expand, node_to_expand.
match);
 
  870  const EdgeIndex parent_edge_index =
 
  871      FindTightExternalEdgeBetweenNodes(to_expand, node_to_expand.
parent);
 
  874  Node& backup_node = nodes_[node_to_expand.
blossom[1]];
 
  879  std::vector<NodeIndex> blossom = std::move(node_to_expand.
blossom);
 
  885    for (
const NodeIndex subnode : SubNodes(n)) {
 
  886      root_blossom_node_[subnode] = n;
 
  898  int blossom_path_start = -1;
 
  899  int blossom_path_end = -1;
 
  900  const NodeIndex start_node = OtherEndFromExternalNode(
 
  901      edges_[parent_edge_index], node_to_expand.
parent);
 
  903      OtherEndFromExternalNode(edges_[match_edge_index], node_to_expand.
match);
 
  904  for (
int i = 0; i < blossom.size(); ++i) {
 
  905    if (blossom[i] == start_node) blossom_path_start = i;
 
  906    if (blossom[i] == end_node) blossom_path_end = i;
 
  911  const std::vector<NodeIndex>& cycle = blossom;
 
  912  std::vector<NodeIndex> path1;
 
  913  std::vector<NodeIndex> path2;
 
  915    const int end_offset =
 
  916        (blossom_path_end + cycle.size() - blossom_path_start) % cycle.size();
 
  917    for (
int offset = 0; offset <=  cycle.size(); ++offset) {
 
  919          cycle[(blossom_path_start + offset) % cycle.size()];
 
  920      if (offset <= end_offset) path1.push_back(node);
 
  921      if (offset >= end_offset) path2.push_back(node);
 
  926  std::reverse(path2.begin(), path2.end());
 
  929  if (path1.size() % 2 == 0) path1.swap(path2);
 
  932  std::vector<NodeIndex>& path_in_tree = path1;
 
  933  const std::vector<NodeIndex>& free_pairs = path2;
 
  936  path2.erase(path2.begin());
 
  941          << absl::StrJoin(path_in_tree, 
", ", absl::StreamFormatter())
 
  942          << 
"] === " << blossom_matched_node;
 
  944          << absl::StrJoin(free_pairs, 
", ", absl::StreamFormatter()) << 
"]";
 
  950  path_in_tree.push_back(blossom_matched_node);
 
  951  CHECK_EQ(path_in_tree.size() % 2, 0);
 
  952  const CostValue tree_dual = nodes_[node_to_expand.
root].tree_dual_delta;
 
  953  for (
int i = 0; i < path_in_tree.size(); ++i) {
 
  955    const bool node_is_plus = i % 2;
 
  961      DCHECK(node_to_expand.
parent != to_expand || n == to_expand);
 
  962      nodes_[n].parent = node_to_expand.
parent;
 
  964      nodes_[n].parent = path_in_tree[i - 1];
 
  968    nodes_[n].root = node_to_expand.
root;
 
  969    nodes_[n].type = node_is_plus ? 1 : -1;
 
  970    nodes_[n].match = path_in_tree[node_is_plus ? i - 1 : i + 1];
 
  973    if (i + 1 == path_in_tree.size()) 
continue;
 
  978    const CostValue adjust = node_is_plus ? -tree_dual : tree_dual;
 
  979    nodes_[n].pseudo_dual += adjust;
 
  980    for (
const NodeIndex subnode : SubNodes(n)) {
 
  981      for (
const EdgeIndex e : graph_[subnode]) {
 
  982        Edge& edge = edges_[e];
 
  983        const NodeIndex other_end = OtherEnd(edge, subnode);
 
  984        if (other_end == n) 
continue;
 
  990        if (other_end != to_expand && !nodes_[other_end].is_internal) {
 
  997          if (nodes_[other_end].type == 0) 
continue;
 
 1002          const Node& other_node = nodes_[other_end];
 
 1003          DCHECK(!plus_plus_pq_.Contains(&edge));
 
 1004          DCHECK(!plus_free_pq_.Contains(&edge));
 
 1005          if (other_node.
IsPlus()) {
 
 1006            plus_plus_pq_.Add(&edge);
 
 1008              primal_update_edge_queue_.push_back(e);
 
 1010          } 
else if (other_node.
IsFree()) {
 
 1011            plus_free_pq_.Add(&edge);
 
 1013              primal_update_edge_queue_.push_back(e);
 
 1024    nodes_[n].parent = n;
 
 1028    for (
const NodeIndex subnode : SubNodes(n)) {
 
 1029      for (
const EdgeIndex e : graph_[subnode]) {
 
 1030        Edge& edge = edges_[e];
 
 1031        const NodeIndex other_end = OtherEnd(edge, subnode);
 
 1032        if (other_end == n) 
continue;
 
 1036        if (other_end != to_expand && !nodes_[other_end].is_internal) {
 
 1042        DCHECK(!plus_plus_pq_.Contains(&edge));
 
 1043        DCHECK(!plus_free_pq_.Contains(&edge));
 
 1044        if (nodes_[other_end].IsPlus()) {
 
 1045          plus_free_pq_.Add(&edge);
 
 1047            primal_update_edge_queue_.push_back(e);
 
 1055  CHECK_EQ(free_pairs.size() % 2, 0);
 
 1056  for (
int i = 0; i < free_pairs.size(); i += 2) {
 
 1057    nodes_[free_pairs[i]].match = free_pairs[i + 1];
 
 1058    nodes_[free_pairs[i + 1]].match = free_pairs[i];
 
 1064    nodes_[n].is_internal = 
false;
 
 
 1070  std::vector<NodeIndex> queue;
 
 1071  for (
NodeIndex n(0); n < nodes_.size(); ++n) {
 
 1072    Node& node = nodes_[n];
 
 1078    if (node.
IsBlossom()) queue.push_back(n);
 
 1082  while (!queue.empty()) {
 
 1083    const NodeIndex to_expand = queue.back();
 
 1086    Node& node_to_expand = nodes_[to_expand];
 
 1090    const EdgeIndex match_edge_index =
 
 1091        FindTightExternalEdgeBetweenNodes(to_expand, node_to_expand.
match);
 
 1094    Node& backup_node = nodes_[node_to_expand.
blossom[1]];
 
 1100    std::vector<NodeIndex> blossom = std::move(node_to_expand.
blossom);
 
 1106      for (
const NodeIndex subnode : SubNodes(n)) {
 
 1107        root_blossom_node_[subnode] = n;
 
 1112    int internal_matched_index = -1;
 
 1113    const NodeIndex matched_node = OtherEndFromExternalNode(
 
 1114        edges_[match_edge_index], node_to_expand.
match);
 
 1115    const int size = blossom.size();
 
 1116    for (
int i = 0; i < size; ++i) {
 
 1117      if (blossom[i] == matched_node) {
 
 1118        internal_matched_index = i;
 
 1122    CHECK_NE(internal_matched_index, -1);
 
 1126    std::vector<NodeIndex> free_pairs;
 
 1127    for (
int i = (internal_matched_index + 1) % size;
 
 1128         i != internal_matched_index; i = (i + 1) % size) {
 
 1129      free_pairs.push_back(blossom[i]);
 
 1133    for (
const NodeIndex to_clear : blossom) {
 
 1134      nodes_[to_clear].type = 0;
 
 1135      nodes_[to_clear].is_internal = 
false;
 
 1136      nodes_[to_clear].parent = to_clear;
 
 1137      nodes_[to_clear].root = to_clear;
 
 1142    const NodeIndex internal_matched_node = blossom[internal_matched_index];
 
 1143    nodes_[internal_matched_node].match = external_matched_node;
 
 1144    nodes_[external_matched_node].match = internal_matched_node;
 
 1147    CHECK_EQ(free_pairs.size() % 2, 0);
 
 1148    for (
int i = 0; i < free_pairs.size(); i += 2) {
 
 1149      nodes_[free_pairs[i]].match = free_pairs[i + 1];
 
 1150      nodes_[free_pairs[i + 1]].match = free_pairs[i];
 
 1155      if (nodes_[n].IsBlossom()) queue.push_back(n);