HDU2471 2008 Asia Regional Hangzhou History of Languages
给出两个DFA的状态转换表,判断两个DFA是否相同。
需要先处理循环路径,即通过某路径后无法达到AC状态,但可能通过该路径后两个DFA的状态转换不相同,这种情况下两个DFA依然是相同的,所以要把这样的路径封死。
从AC状态反向建图,BFS封死上述路径,再从0状态BFS同步对比两DFA状态转换。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<queue> 5 using namespace std; 6 const int maxn = 2011; 7 const int maxm = 27; 8 9 bool vis[maxn][maxn], ac1[maxn], ac2[maxn]; 10 int f1[maxn][maxm], f2[maxn][maxm]; 11 int t, n1, n2; 12 struct qu 13 { 14 int s1, s2; 15 qu() 16 { 17 s1 = s2 = 0; 18 } 19 qu(int a, int b) 20 { 21 s1 = a, s2 = b; 22 } 23 }; 24 queue<qu> q; 25 bool BFS() 26 { 27 qu lin; 28 memset(vis, 0, sizeof(vis)); 29 while(!q.empty()) q.pop(); 30 q.push(qu()), vis[0][0] = true; 31 while(!q.empty()) 32 { 33 lin = q.front(), q.pop(); 34 if(lin.s1 >= n1 || lin.s2 >= n2) return false; 35 if(ac1[lin.s1] != ac2[lin.s2]) return false; 36 for(int i = 0; i < t; ++ i) 37 { 38 if(!!(f1[lin.s1][i] + 1) != !!(f2[lin.s2][i] + 1)) return false; 39 if(f1[lin.s1][i] == -1)continue; 40 if(!vis[f1[lin.s1][i]][f2[lin.s2][i]]) 41 { 42 vis[f1[lin.s1][i]][f2[lin.s2][i]] = true; 43 q.push(qu(f1[lin.s1][i], f2[lin.s2][i])); 44 } 45 } 46 } 47 return true; 48 } 49 int fst[maxn], nex[maxn *maxn], v[maxn *maxn], wnum; 50 bool ok[maxn]; 51 void BFSCUT(bool *ac, int n) 52 { 53 queue<int> q; 54 int i; 55 memset(ok, 0, sizeof(ok)); 56 for(i = 0; i < n; ++ i) if(ac[i]) q.push(i), ok[i] = true; 57 while(!q.empty()) 58 { 59 for(i = fst[q.front()], q.pop(); i != -1; i = nex[i]) 60 if(!ok[v[i]]) ok[v[i]] = true, q.push(v[i]); 61 } 62 } 63 void ReadData(bool *ac, int f[][maxm], int *n) 64 { 65 scanf("%d", n); 66 memset(fst, -1, sizeof(fst)); 67 wnum = 0; 68 for(int i = 0, x; i < *n; ++ i) 69 { 70 scanf("%d", &x), ac[i] = x; 71 for(int j = 0; j < t; ++ j) 72 { 73 scanf("%d", &f[i][j]); 74 if(f[i][j] != -1) 75 { 76 nex[wnum] = fst[f[i][j]]; 77 fst[f[i][j]] = wnum; 78 v[wnum] = i; 79 ++ wnum; 80 } 81 } 82 } 83 BFSCUT(ac, *n); 84 for(int i = 0; i < *n; ++ i) 85 for(int j = 0; j < t; ++ j) 86 if(f[i][j] != -1 && !ok[f[i][j]]) f[i][j] = -1; 87 } 88 int main() 89 { 90 int ca = 0; 91 while(scanf("%d", &t), t) 92 { 93 ReadData(ac1, f1, &n1); 94 ReadData(ac2, f2, &n2); 95 printf("Case #%d: ", ++ ca); 96 printf(BFS() ? "Yes\n" : "No\n"); 97 } 98 return 0; 99 }