csu 1951: 图样 AC自动机
来源:互联网 发布:筛选的数据求和 编辑:程序博客网 时间:2024/04/29 21:34
题目链接点这里
我们把两种字符串都插入到自动机中,用End[u] = mask来状压记录下以u节点结尾的喜欢字符串有哪些(比如这个点结尾有第i个字符串和第j个字符串,,那么End[u]=(1<<i)+(1<<j) )。
之后那我们把讨厌字符串的End[u]记为-1.。
构造出自动机之后,套路状态转移建图。然后bfs就好了 ,什么?你不会ac自动机上的状态转移?请做这题
#include<iostream>#include<cstdio>#include<math.h>#include<algorithm>#include<map>#include<set>#include<bitset>#include<unordered_map>#include<stack>#include<queue>#include<string.h>#include<cstring>#include<vector>#include<time.h>#include<stdlib.h>using namespace std;#define INF 0x3f3f3f3f#define INFLL 0x3f3f3f3f3f3f3f3f#define FIN freopen("input.txt","r",stdin)#define mem(x,y) memset(x,y,sizeof(x))typedef unsigned long long ULL;typedef long long LL;#define fuck(x) cout<<"q"<<endl;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1typedef pair<pair<int,int>,int> PIII;typedef pair<int,int> PII;const double eps=1e-8;const int MX=555;const int P=1e9+7;int n,m;char s[1000+10];struct AC_trie{ int root,cnt; int End[5000+10],to[5000+10][10],fail[5000+10];//改 int newnode() { for(int i=0; i<10; i++) to[cnt][i]=0;//改 End[cnt]=0; return cnt++; } void init() { cnt=1; root=newnode(); } void insert(char *s,int w)//0无,0到n-1是喜欢,-1是讨厌 { int now=root; for(char *ss=s; *ss; ss++) { int v=*ss-'a';//改 if(!to[now][v])to[now][v]=newnode(); now=to[now][v]; } if(w!=-1) End[now]|=(1<<w);//改 else End[now]=-1;//改 } void build() { queue<int> my; fail[root]=root; for(int i = 0; i < 10; i++)//改 if(!to[root][i]) to[root][i]= root; else { fail[to[root][i]]=root; my.push(to[root][i]); } while(!my.empty()) { int u=my.front(); my.pop(); for(int i=0; i<10; i++) //改 { int v=to[u][i]; if(v) { fail[v]=to[fail[u]][i]; my.push(v); } else to[u][i]=to[fail[u]][i]; if(End[u]==-1)continue; if(End[fail[u]]==-1)End[u]=-1; else End[u]|=End[fail[u]]; } } } int head[MX],edge_cnt; struct Edge { int nxt,to; char c; } E[MX*MX]; void edge_init() { mem(head,-1); edge_cnt=0; } void edge_add(int u,int v,char c) { E[edge_cnt].nxt=head[u]; E[edge_cnt].to=v; E[edge_cnt].c=c; head[u]=edge_cnt++; } void build_edge() { edge_init(); for(int i=1; i<cnt; i++) { for(int j=0; j<10; j++) if(End[to[i][j]]!=-1&&i!=to[i][j]) { edge_add(i,to[i][j],'a'+j); } } } int d[MX][1<<15]; int pre[MX][1<<15][3]; int bfs() { for(int i=1; i<cnt; i++) for(int j=0; j<(1<<n); j++)d[i][j]=0; int t=(1<<n)-1; queue<PII> Q; Q.push(PII(1,0)); d[1][0]=0; while(!Q.empty()) { int u=Q.front().first,s=Q.front().second; Q.pop(); for(int i=head[u]; ~i; i=E[i].nxt) { int v=E[i].to; int ss=s; if(End[v]!=-2)ss|=End[v]; if(d[v][ss]==0) { pre[v][ss][0]=u; pre[v][ss][1]=s; pre[v][ss][2]=E[i].c-'a'; d[v][ss]=d[u][s]+1; Q.push(PII(v,ss)); } if(ss==t)return v; } } return -1; } char ss[11111]; char* print(int s) { int cnt=0; int now=s,w=(1<<n)-1; while(now!=1||w!=0) { int tnow=now,tw=w; ss[cnt++]=pre[tnow][tw][2]+'a'; now=pre[tnow][tw][0]; w=pre[tnow][tw][1]; } ss[cnt]=0; reverse(ss,ss+cnt); return ss; }} AC;int main(){ FIN; while(cin>>n>>m) { AC.init(); for(int i=0; i<n; i++) { scanf("%s",s); AC.insert(s,i); } for(int i=0; i<m; i++) { scanf("%s",s); AC.insert(s,-1); } AC.build(); AC.build_edge(); int ans=AC.bfs(); if(ans!=-1) { puts(AC.print(ans)); } else puts("-"); } return 0;}
阅读全文
0 0
- csu 1951: 图样 AC自动机
- AC自动机...
- AC自动机
- AC 自动机
- AC自动机
- AC自动机
- ac自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC 自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- 两位小数点
- 深入理解Redis中的主键失效及其实现机制
- 05-rabbitmq-发布订阅
- Dubbo架构设计详解
- VB 二进制文件put函数保存数组
- csu 1951: 图样 AC自动机
- ElasticSearch 5 安装部署常见错误或问题
- 并发编程4:Java 阻塞队列源码分析(上)
- 全面剖析synchronized
- Python爬虫-Selenium爬取淘宝美食
- centos7-elasticsearch安装配置
- 高效能人士的七个习惯——由内而外全面造就自己
- 从zip文件中读取数据
- centos文件操作