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;
}