Cod sursa(job #2588152)

Utilizator Constantin.Dragancea Constantin Constantin. Data 24 martie 2020 15:09:30
Problema NFA Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.97 kb
#include <bits/stdc++.h>
using namespace std;

#define N 1010
#define SZ 40
#define fi first
#define se second
int n, m, start, t, queries;
vector <int> v[N][SZ], g[N][SZ];
vector <string> sol;
bool fn[N], isUseless[N];
string word;

struct lol{
    int node, len;

    bool operator<(const lol &other)const{
        if (len == other.len) return node < other.node;
        else return len < other.len;
    }
};
map <lol, bool> badStates;

ifstream in ("nfa.in");
ofstream out ("nfa.out");

void read(){
    in >> n >> m >> t;
    in >> start;
    for (int i=0, x; i<t; i++){
        in >> x;
        fn[x] = 1;
    }
    for (int i=0, x, y; i<m; i++){
        char c;
        in >> x >> y >> c;
        v[x][c - 'a'].push_back(y);
        g[y][c - 'a'].push_back(x);
    }
    /*
    for (int i=1; i<=n; i++){
        for (int j='a'; j<='z'; j++){
            int len = v[i][j].size();
            for (int k=0; k < len; k++)
                if (v[i][j][k] == i) swap(v[i][j][k], v[i][j][len - 1]), len--;
        }
    }
    */
}

bool check(int nod, int idx){
    if (idx == word.length()) return fn[nod];
    if (!v[nod][word[idx] - 'a'].size()) return 0;
    bool flag = 0;
    for (auto it: v[nod][word[idx] - 'a']){
        if (isUseless[it]) continue;
        if (badStates[{it, idx+2}]) continue;
        if (check(it, idx + 1)) return 1;
    }
    badStates[{nod, idx + 1}] = 1;
    return 0;
}

void firstWords(){
    queue <pair<int, string> > Q;
    Q.push({start, ""});
    while (sol.size() <= 100 && !Q.empty()){
        pair <int, string> curr = Q.front();
        Q.pop();
        for (int i='a'; i<='z'; i++){
            for (auto it: v[curr.fi][i - 'a']){
                if (isUseless[it]) continue;
                if (fn[it]) sol.push_back(curr.se + char(i));
                Q.push({it, curr.se + char(i)});
            }
        }
    }
    while (sol.size() > 100) sol.pop_back();
    out << "primele " << sol.size() << " cuvinte posibile:\n";
    for (auto it: sol) out << it << '\n';
}

void checkWords(){
    in >> queries;
    getline(in, word);
    while (queries--){
        getline(in, word);
        out << check(start, 0) << '\n';
        //out << "Cuvantul " << word;
        //if (!check(start, 0)) out << " nu";
        //out << " apartine automatului\n";
        badStates.clear();
    }
}

void removeUselessStates(){
    queue <int> Q;
    for (int i=1; i<=n; i++)
        if (fn[i]) Q.push(i), isUseless[i] = 1;
    while (!Q.empty()){
        int nod = Q.front();
        Q.pop();
        for (char c='a'; c<='z'; c++){
            for (auto it: g[nod][c - 'a'])
                if (!isUseless[it]) Q.push(it), isUseless[it] = 1;
        }
    }
    for (int i=1; i<=n; i++) isUseless[i] = !isUseless[i];
}

int main(){
    ios_base::sync_with_stdio(0); in.tie(0); out.tie(0);

    read();

    removeUselessStates();

    checkWords();

    //firstWords();

    return 0;
}