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 }
posted @ 2012-08-28 01:08  CSGrandeur  阅读(376)  评论(3编辑  收藏  举报