void solve(std::istream& in, std::ostream& out) { startTime = chrono::system_clock::now(); in >> n; rb.resize(n); for (int i = 0; i < n; i++) { in >> rb[i].first >> rb[i].second; } State state = State(0, vbb()); State s = chokudaiSearch(state); if (s.second.size() == 0 || s.first != 0) { out << -1 << '\n'; } else { for (int i = 0; i < s.second.size(); i++) { out << (s.second[i] ? '1' : '0'); } out << '\n'; } }
/** * Scan the CFG for finding exit and builds virtual edges with entry and exit. * For memory-place and time purposes, this method is only called when the CFG * is used (call to an accessors method). */ void CFG::scan(void) { // Prepare data typedef HashTable<BasicBlock *, BasicBlock *> map_t; map_t map; VectorQueue<BasicBlock *> todo; todo.put(ent); // Find all BB _bbs.add(&_entry); while(todo) { BasicBlock *bb = todo.get(); ASSERT(bb); // second case : calling jump to a function if(map.exists(bb) || (bb != ent && ENTRY(bb))) continue; // build the virtual BB BasicBlock *vbb = new VirtualBasicBlock(bb); _bbs.add(vbb); map.put(bb, vbb); ASSERTP(map.exists(bb), "not for " << bb->address()); // resolve targets for(BasicBlock::OutIterator edge(bb); edge; edge++) { ASSERT(edge->target()); if(edge->kind() != Edge::CALL) todo.put(edge->target()); } } // Relink the BB BasicBlock *vent = map.get(ent, 0); ASSERT(vent); new Edge(&_entry, vent, Edge::VIRTUAL); for(bbs_t::Iterator vbb(_bbs); vbb; vbb++) { if(vbb->isEnd()) continue; BasicBlock *bb = ((VirtualBasicBlock *)*vbb)->bb(); if(bb->isReturn()) new Edge(vbb, &_exit, Edge::VIRTUAL); for(BasicBlock::OutIterator edge(bb); edge; edge++) { // A call if(edge->kind() == Edge::CALL) { Edge *vedge = new Edge(vbb, edge->target(), Edge::CALL); vedge->toCall(); } // Pending edge else if(!edge->target()) { new Edge(vbb, 0, edge->kind()); } // Possibly a not explicit call else { ASSERT(edge->target()); BasicBlock *vtarget = map.get(edge->target(), 0); if(vtarget) new Edge(vbb, vtarget, edge->kind()); else { // calling jump to a function Edge *nedge = new Edge(vbb, edge->target(), Edge::CALL); vbb->flags |= BasicBlock::FLAG_Call; new Edge(vbb, &_exit, Edge::VIRTUAL); } } } } _bbs.add(&_exit); // Number the BB for(int i = 0; i < _bbs.length(); i++) { INDEX(_bbs[i]) = i; _bbs[i]->_cfg = this; } flags |= FLAG_Scanned; }