Cod sursa(job #1714284)

Utilizator Andrei1998Andrei Constantinescu Andrei1998 Data 7 iunie 2016 22:08:06
Problema Robo Scor 0
Compilator cpp Status done
Runda Arhiva ICPC Marime 3.15 kb
#include <fstream>
#include <cassert>
#include <algorithm>
#include <vector>
#include <string>
#include <cstring>
#include <sstream>
#include <utility>

using namespace std;

const int NMAX = 5200;
const int SIGMAMAX = 10;

class Automaton {
public:
    Automaton(int n, int sigma, int q0 = 0): N(n), SIGMA(sigma), Q0(q0) {}

    void add_final_state(int node) {
        f.push_back(node);
    }

    void add_transition(int node1, char c, int node2) {
        trans[node1][c - 'a'] = node2;
    }

    int minimize() {
        //Set labels according to accepting states
        memset(labels, 0, sizeof labels);
        for (auto it: f)
            labels[it] = 1;

        int labels_count_init = 0;
        while (1) {
            for (int i = 0; i < N; ++ i)
                labels_count_init = max(labels_count_init, labels[i]);

            //Built auxiliary transition table
            for (int i = 0; i < N; ++ i) {
                sortable_table[i].first.resize(SIGMA);
                sortable_table[i].second = i;

                for (int j = 0; j < SIGMA;  ++ j) {
                    if (labels[trans[i][j]] != labels[i])
                        table[i][j] = labels[trans[i][j]];
                    else
                        table[i][j] = -1;
                    sortable_table[i].first[j] = table[i][j];
                }
            }

            //Sort the table
            sort(sortable_table, sortable_table + N);

            //Relabel
            int label = 0;
            for (int i = 0; i < N; ++ i) {
                if (!i || sortable_table[i].first != sortable_table[i - 1].first)
                    ++ label;
                labels[sortable_table[i].second] = label;
            }

            if (labels_count_init == label)
                break;
        }

        return labels_count_init;
    }

    /*void print() {
        cout << "The finals are " << endl;
        for (auto it: f)
            cout << it << ' ';
        cout << endl;

        for (int i = 0; i < N; ++ i) {
            cout << "i = " << i << " -> ";
            for (int j = 0; j < SIGMA; ++ j)
                cout << trans[i][j] << ' ';
            cout << endl;
        }
    }*/
private:
    const int N;
    const int SIGMA;
    const int Q0;

    vector <int> f;
    int trans[NMAX][SIGMAMAX];

    int table[NMAX][SIGMAMAX];
    int labels[NMAX];
    pair <vector <int>, int> sortable_table[NMAX];
};

int main()
{
    ifstream cin("robo.in");
    ofstream cout("robo.out");

    int t = 0;
    cin >> t;

    while (t --) {
        int n, sigma;
        cin >> n >> sigma; cin.ignore();

        Automaton aut(n, sigma);

        string str;
        getline(cin, str);
        stringstream ss(str + " ");

        int node;
        while (ss >> node)
            aut.add_final_state(node);

        int a, b;
        char c;
        for (int i = 0; i < n * sigma; ++ i) {
            cin >> a >> c >> b;
            aut.add_transition(a, c, b);
        }

        //aut.print();
        cout << aut.minimize() << '\n';
    }

    cin.close();
    cout.close();
    return 0;
}