ADDED lib/graph/dfa_hopcroft.cpp Index: lib/graph/dfa_hopcroft.cpp ================================================================== --- lib/graph/dfa_hopcroft.cpp +++ lib/graph/dfa_hopcroft.cpp @@ -0,0 +1,111 @@ +// TODO : optimize to O(n log n) +// current version looks to be running in O(n^2) ... orz +// +// TODO : clean up as a library +// +// Copy&Paste from SRM562 Div1 Hard + + // Input is given as: + // v----c---->G[v][c] + // Must be a complete automaton. + // !!! The following code is assuming |c|==4 !!! + // + // !!! The following code is assuming the final state is {0}. + // + mint solve(vector< vector >& G) + { + vector< vector > set_buffer; + set active_sets; + set active_splitters; + + { + set_buffer.push_back( vector(1,0) ); + vector all; + for(int v=1; v& splv = set_buffer[*active_splitters.begin()]; + set spl(splv.begin(), splv.end()); + active_splitters.erase(active_splitters.begin()); + + for(int d=0; d<4; ++d) + for(set::iterator it=active_sets.begin(); it!=active_sets.end(); ) + { + int ii = *it++; + const vector& cur = set_buffer[ii]; + vector t, f; + for(int k=0; k es; + for(set::iterator it=active_sets.begin(); it!=active_sets.end(); ++it) + if(*it) + es.push_back(set_buffer[*it].size()); +/* + for(bool changed=true; changed;) + { + changed=false; + for(int i=0; i spl(eqs[i].first.begin(), eqs[i].first.end()); + eqs[i].second = true; + for(int k=0; k t, f; + for(vector::iterator it=eqs[k].first.begin(); it!=eqs[k].first.end(); ++it) + (spl.count(G[*it][d]) ? t : f).push_back(*it); + if(!t.empty() && !f.empty()) { + if(eqs[k].second) { + eqs.push_back(make_pair(t,t.size()>f.size())); + eqs.push_back(make_pair(f,t.size()<=f.size())); + dead.push_back(false); + dead.push_back(false); + changed = true; + } else { + eqs.push_back(make_pair(t,false)); + eqs.push_back(make_pair(f,false)); + dead.push_back(false); + dead.push_back(false); + changed = true; + } + dead[k] = true; + } + } + } + } + + vector es; + for(int i=1; i