void findShortestPaths(string node, int indx, unordered_map<string, unordered_set<string>>& parents, vector<string>& solution, vector<vector<string>>& result) {
     if(parents[node].find(node) != parents[node].end()) {
         assert(indx == 0);
         solution[indx] = node;
         result.push_back(solution);
         return;
     }
     solution[indx] = node;
     for(auto parentIter = parents[node].begin(); parentIter != parents[node].end(); ++parentIter) {
         findShortestPaths(*parentIter, indx - 1, parents, solution, result);
     }
 }
 vector<vector<string>> findLadders(string beginWord, string endWord, unordered_set<string> &wordList) {
     queue<string> Q;
     unordered_map<string, bool> visited;
     unordered_map<string, int> level;
     unordered_map<string, unordered_set<string>> parents;
     Q.push(beginWord);
     level[beginWord] = 1;
     parents[beginWord].insert(beginWord);
     int depth = INT_MAX;
     while(!Q.empty()) {
         string node = Q.front();
         visited[node] = true;
         Q.pop();
         if(level[node] > depth) {
             break;
         }
         if(level[node] == depth and node != endWord) {
             continue;    
         }
         if(isNextState(node, endWord)) {
             level[endWord] = level[node] + 1;
             parents[endWord].insert(node);
             Q.push(endWord);
             depth = level[endWord];
             continue;
         }
         vector<string> neighs;
         findAdjList(node, wordList, neighs);
         for(int i = 0; i < (int)neighs.size(); ++i) {
             string neigh = neighs[i];
             if(level[neigh] > 0) {
                 if(level[node] >= level[neigh]) {
                     continue;
                 }
             }
             if(!visited[neigh]) {
                 Q.push(neigh);
                 parents[neigh].insert(node);
                 level[neigh] = level[node] + 1;
                 if(neigh == endWord) {
                     depth = level[neigh];
                 }
             }
         }
     }
     vector<vector<string>> result;
     if(depth == INT_MAX) return result;
     vector<string> solution(depth, "");
     findShortestPaths(endWord, depth - 1, parents, solution, result);
     return result;
 }
Пример #3
0
void Search::Run(const Inputs &inputs) {
    for(Inputs::const_iterator ngi = inputs.begin(); ngi!=inputs.end(); ++ngi) {
        node_iter ni;
        for(ni = nodes().begin(); ni!=nodes().end(); ++ni)
            if(gd<Name>(*ni)==ngi->first) {
                StrGraph &dest = gd<SearchStage>(*ni).result;
                dest = *ngi->second;
                break;
            }
        /*
        if(ni==nodes().end())
            throw StageNotFound(ngi->first);
        */
    }
    while(1) {
        Node *stage = 0;
        // find a stage for which all prereq stages are done
        for(node_iter ni = nodes().begin(); ni!=nodes().end(); ++ni) {
            if(gd<SearchStage>(*ni).done)
                continue;
            inedge_iter ei;
            for(ei = (*ni)->ins().begin(); ei!=(*ni)->ins().end(); ++ei)
                if(!gd<SearchStage>((*ei)->tail).done)
                    break;
            if(ei==(*ni)->ins().end()) {
                stage = *ni;
                break;
            }
        }
        if(!stage)
            break;
        SearchStage &earchage = gd<SearchStage>(stage);
        Search::inedge_iter ei = stage->ins().begin();
        if(ei!=stage->ins().end())
            switch(earchage.type) {
            case UnionInquiry:
                earchage.result = gd<SearchStage>((*ei)->tail).result;
                for(; ei!=stage->ins().end(); ++ei)
                    earchage.result |= gd<SearchStage>((*ei)->tail).result;
                break;
            case IntersectionInquiry:
                earchage.result = gd<SearchStage>((*ei)->tail).result;
                for(; ei!=stage->ins().end(); ++ei)
                    earchage.result &= gd<SearchStage>((*ei)->tail).result;
                break;
            case PatternInquiry: {
                if(!earchage.pattern)
                    throw PatternNotThere();
                earchage.result.clear();
                queue<Match> Q;
                PathsFollowed followed;
                for(; ei!=stage->ins().end(); ++ei) {
                    Name inputname = gd<Name>(*ei);
                    Pattern::node_iter ni;
                    for(ni = earchage.pattern->nodes().begin();
                            ni!=earchage.pattern->nodes().end(); ++ni)
                        if(gd<Name>(*ni)==inputname) {
                            StrGraph &input = gd<SearchStage>((*ei)->tail).result;
                            for(StrGraph::node_iter inpi = input.nodes().begin(); inpi !=input.nodes().end(); ++inpi) {
                                earchage.result.insert(*inpi);
                                Q.push(Match(*ni,source.find(*inpi)));
                            }
                            break;
                        }
                    if(ni==earchage.pattern->nodes().end())
                        throw PatternStateNotFound(inputname);
                }
                runPattern(Q,followed,earchage.limit,&earchage.result);
                break;
            }
            case PathInquiry: {
                earchage.result.clear();
                StrGraph *a = 0, *b = 0;
                for(; ei!=stage->ins().end(); ++ei) {
                    DString inputname = gd<Name>(*ei);
                    if(inputname=="a")
                        a = &gd<SearchStage>((*ei)->tail).result;
                    else if(inputname=="b")
                        b = &gd<SearchStage>((*ei)->tail).result;
                }
                if(a&&b)
                    if(earchage.shortest)
                        findShortestPaths(source,*a,*b,earchage.weightattr,earchage.limit,earchage.result);
                    else
                        findAllPaths(source,*a,*b,earchage.goOut,earchage.goIn,earchage.firstOnly,earchage.limit,earchage.result);
            }
            }
        earchage.done = true;
    }
}