题意:给你两个自动机,求出最短的(如果有相同最短的则求出字典序最小的)能被其中一个自动机接收而不能被另外一个自动机接收的字符串。

一看是自动机以为是神题,后来比赛最后才有思路。

两个自动机的状态都是小于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;
}

最新文章

  1. Redis(一) 介绍
  2. tomcat切割日志的shell脚本
  3. poj2182
  4. 【PHP】解决html网页乱码问题
  5. PHPCMS V9.3.2用户注册模板中的一个低级Bug
  6. poj 2586 Y2K Accounting Bug(贪心算法,水题一枚)
  7. html - table 表格不被撑开,td某些列宽度固定某些列自适应
  8. hdu_4823_Energy Conversion
  9. Linux下 两台机器文件/文件夹 相互拷贝
  10. windows下用pip安装软件超时解决方案
  11. 前向分步算法 &amp;&amp; AdaBoost算法 &amp;&amp; 提升树(GBDT)算法 &amp;&amp; XGBoost算法
  12. 在Go语言中基础的Redis操作
  13. 09-HTML-form标签
  14. elinks快捷方式
  15. Docker 安装私有镜像库的简单使用
  16. 自定义cnblogs样式小结
  17. 新生代老年代GC组合
  18. win7 64位安装pywin32
  19. 二、jenkins配置email(以腾讯企业qq为例)
  20. 利用大数据技术处理海量GPS数据

热门文章

  1. android systemtrace 报错
  2. HA集群中namenode连接不上journalnode,导致namenode启动不了
  3. 《1024伐木累-周末特别篇》-中彩票了,开发APP
  4. ueditor搭建图片服务器
  5. Python 3基础教程15-读文件内容
  6. 利用jsoup抓取网页图片
  7. Leetcode 670.最大交换
  8. hdu 1007 Quoit Design (最近点对问题)
  9. swiper使用案例一
  10. 70种简单常用的JS代码