HDU 5487 Difference of Languages BFS

题意:

给两个DFA,求一个最短而且字典序最小的字符串使得该串能被一个DFA识别但不能被另一个DFA识别。

分析:

直接BFS就好,状态为两个DFA的笛卡尔乘积,也就是当前第一个DFA走到了S1,第二个DFA走到了S2。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#define MP make_pair
using namespace std;

typedef pair<int, int> PII;

const int maxn = 1000 + 10;

int n1, n2;

struct DFA
{
    int n, m, k;
    int accept[maxn];
    int G[maxn][26];

    void init() {
        memset(accept, 0, sizeof(accept));
        memset(G, 0, sizeof(G));
        scanf("%d%d%d", &n, &m, &k);
        for(int x, i = 0; i < k; i++) {
            scanf("%d", &x);
            accept[x + 1] = 1;
        }
        for(int u, v, i = 0; i < m; i++) {
            char s[5];
            scanf("%d%d%s", &u, &v, s);
            G[u+1][s[0]-'a'] = v+1;
        }
    }
};

DFA A, B;

bool vis[maxn][maxn];
int p[maxn][maxn], t[maxn][maxn];

int encode(int S1, int S2) {
    return S1 * n1 + S2;
}

void decode(int code, int& S1, int& S2) {
    S1 = code / n1;
    S2 = code % n1;
}

void BFS() {
    memset(vis, false, sizeof(vis));
    memset(p, -1, sizeof(p));
    queue<PII> Q;
    Q.push(MP(1, 1));
    vis[1][1] = true;

    while(!Q.empty()) {
        PII x = Q.front(); Q.pop();
        int S1 = x.first, S2 = x.second;
        if(A.accept[S1] ^ B.accept[S2]) {
            vector<char> ans;
            while(p[S1][S2] != -1) {
                ans.push_back(t[S1][S2]);
                decode(p[S1][S2], S1, S2);
            }
            reverse(ans.begin(), ans.end());
            for(int i = 0; i < ans.size(); i++) printf("%c", 'a' + ans[i]);
            printf("\n");
            return ;
        }

        for(int i = 0; i < 26; i++) {
            int _S1 = A.G[S1][i], _S2 = B.G[S2][i];
            if(vis[_S1][_S2]) continue;
            vis[_S1][_S2] = true;
            p[_S1][_S2] = encode(S1, S2);
            t[_S1][_S2] = i;
            Q.push(MP(_S1, _S2));
        }
    }

    printf("0\n");
}

int main() {
    //freopen("in.txt", "r", stdin);

    int T; scanf("%d", &T);
    for(int kase = 1; kase <= T; kase++) {
        A.init();
        B.init();
        n1 = A.n + 1, n2 = B.n + 1;
        printf("Case #%d: ", kase);
        BFS();
    }

    return 0;
}

posted @ 2015-10-09 21:55  AOQNRMGYXLMV  阅读(162)  评论(0编辑  收藏  举报