HDU5487 Difference of Languages(BFS)
2015-09-28 10:43
267 查看
题意:给你两个自动机,求出最短的(如果有相同最短的则求出字典序最小的)能被其中一个自动机接收而不能被另外一个自动机接收的字符串。
一看是自动机以为是神题,后来比赛最后才有思路。
两个自动机的状态都是小于1000的,所以可以建一个图,每个结点(u,v)表示当前处于自动机1的状态u和自动机2的状态v,然后相应的这些状态接收[a-z]的字符就会转移到下一个状态。然后从原点(0,0)开始广搜,搜到的第一个accpet[u]!=accept[v]的即是所求的状态。(处理的时候要给每个自动机加一个状态,用来表示失配的时候的情况,这个状态的所有后继都转移向自己,而且本身不是accpet状态,广搜即可)
一看是自动机以为是神题,后来比赛最后才有思路。
两个自动机的状态都是小于1000的,所以可以建一个图,每个结点(u,v)表示当前处于自动机1的状态u和自动机2的状态v,然后相应的这些状态接收[a-z]的字符就会转移到下一个状态。然后从原点(0,0)开始广搜,搜到的第一个accpet[u]!=accept[v]的即是所求的状态。(处理的时候要给每个自动机加一个状态,用来表示失配的时候的情况,这个状态的所有后继都转移向自己,而且本身不是accpet状态,广搜即可)
#pragma warning(disable:4996) #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <vector> #include <cmath> #include <queue> using namespace std; #define maxn 1005 int n1, m1, k1; int n2, m2, k2; bool tar1[maxn]; bool tar2[maxn]; int go1[maxn][26]; int go2[maxn][26]; int prestate[maxn*maxn]; char prechar[maxn*maxn]; bool vis[maxn*maxn]; bool check(int x) { return tar1[x / n2] != tar2[x%n2]; } int nextState(int x, int c) { return go1[x / n2][c] * n2 + go2[x%n2][c]; } int main() { int T; cin >> T; int ca = 0; while (T--) { memset(go1, -1, sizeof(go1)); memset(go2, -1, sizeof(go2)); memset(tar1, 0, sizeof(tar1)); memset(tar2, 0, sizeof(tar2)); int accept; int ui, vi; char ci[3]; scanf("%d%d%d", &n1, &m1, &k1); for (int i = 0; i < k1; ++i){ scanf("%d", &accept); tar1[accept] = true; } for (int i = 0; i < m1; ++i){ scanf("%d%d%s", &ui, &vi, ci); go1[ui][ci[0] - 'a'] = vi; } for (int i = 0; i <= n1; ++i){ for (int k = 0; k < 26; ++k){ if (go1[i][k] == -1) go1[i][k] = n1; } } scanf("%d%d%d", &n2, &m2, &k2); for (int i = 0; i < k2; ++i){ scanf("%d", &accept); tar2[accept] = true; } for (int i = 0; i < m2; ++i){ scanf("%d%d%s", &ui, &vi, ci); go2[ui][ci[0] - 'a'] = vi; } for (int i = 0; i <= n2; ++i){ for (int k = 0; k < 26; ++k){ if (go2[i][k] == -1) go2[i][k] = n2; } } ++n1; ++n2; int ans = -1; memset(vis, 0, sizeof(vis)); queue<int> Q; Q.push(0); vis[0] = true; while (!Q.empty()) { int state = Q.front(); Q.pop(); if (check(state)){ ans = state; break; } for (int k = 0; k < 26; ++k){ int nstate = nextState(state, k); if (!vis[nstate]){ Q.push(nstate); vis[nstate] = true; prestate[nstate] = state; prechar[nstate] = k; } } } if (-1 == ans){ printf("Case #%d: 0\n", ++ca); continue; } string ts; while (ans != 0){ ts.push_back(char('a' + prechar[ans])); ans = prestate[ans]; } reverse(ts.begin(), ts.end()); printf("Case #%d: %s\n", ++ca, ts.c_str()); } return 0; }
相关文章推荐
- 使用CreateJS绘制图形
- CSS的position属性详解
- jQuery源码分析之深入理解jQuery.data,jQuery._data以及data实例函数十八问
- jquery 输入框自动提示
- jquery js 传递对象 数组
- CSS的定位原理
- html限制文本框只能输入数字和一个小数点
- RTEMS4.11 FEDORA20 64BIT环境搭建
- 深度学习(五)caffe环境搭建
- js中let和var定义变量的区别
- js中的empty()和remove()的区别
- CSS3绘制圆角矩形的简单示例
- AngularJs核心概览
- CSS实现菜单背景自适应宽度的方法
- 一组惊艳的NodeJs包
- jquery 页面校验器的使用
- CSS3 Filter详解(改变模糊度 亮度 透明度等方法)
- css
- Angular指令、service封装经验总结
- jquery validate异步验证时多参数传递