HDU 2896 病毒侵袭 AC自动机

来源:互联网 发布:电脑免费恢复数据软件 编辑:程序博客网 时间:2024/06/11 09:45

   这道题是一道典型的AC自动机,如果对AC自动机了解的话,很容易就能A出来,如果你是用指针写的话,会出现超内存的错误,因为我刚开始就是用指针写的,然后又各种从网上百度,百度到所有用指针写的,复制粘贴上去都出现超内存的错误,后来用了静态数组谢了之后就过了。这道题卡的点也有输入跟输出这一块。

用指针写的代码:

#include<iostream>#include<cstdio>#include<cstring>#include<queue>using namespace std;struct node {int count,index;node *fail;node *next[300];node() {index = 0;fail = 0;count=0;memset(next,0,sizeof(next));}} *q[1000000];int head=0,tail=0;priority_queue<int, vector<int>, greater<int> > que;node *root = new node(),*p1,*p2;void insert(int num,char s[]) {int i=0;p1 = root;while(s[i]) {int val = (int)s[i] ;if(p1->next[val] == 0) {p2=new node();p1->next[val] = p2;p1 = p2;}else p1 = p1->next[val];i++;}p1->index= num;p1->count++;}void build_ac_automation() {root->fail = 0;q[head++] = root;while(head != tail) {p1 = q[tail++];for(int i=0; i<300; i++) {if(p1->next[i]) {if(p1 == root) p1->next[i]->fail = root;else {p2=p1->fail;while(p2) {if(p2->next[i]) {p1->next[i]->fail = p2->next[i];break;}p2 = p2->fail;}if(p2 == 0) p1->next[i]->fail = root;}q[head++] = p1->next[i];}}}}void query(char s[]) {int i=0;p1=root;while(s[i]) {int val = (int)s[i] ;while(p1->next[val]==0 && p1!=root) p1 = p1->fail;p1 = p1->next[val];p1 = (p1==0) ? root : p1;p2=p1;while(p2!=root && p2->count!=-1) {if(p2->count) que.push(p2->index);p2->count=-1;p2 = p2->fail;}i++;}}int main() {int n,m,i,num=0;char s[505],st[10010];cin>>n;for(i=1; i<=n; i++) {cin>>s;insert(i,s);}cin>>m;build_ac_automation();for(i=1; i<=m; i++) {cin>>st;while(!que.empty()) que.pop();query(st);if(!que.empty()) {cout<<"web "<<i<<":";while(!que.empty()) {cout<<' '<<que.top();que.pop();}cout<<endl;num++;}}cout<<"total: "<<num<<endl;return 0;}
用静态数组写的代码如下:

#include<iostream> #include<cstdio>#include<cstring>#include<queue>using namespace std;struct node{int next[500*210][128],fail[500*210],vis[500*210];int sz,root;int newnode() {memset(next[sz],0,sizeof(next[sz]));vis[sz++] = 0;return sz-1;}void init() {sz=0;root = newnode();}void insert(char s[],int id) {int i,pre=root;for(i=0; s[i]; i++) {if(next[pre][s[i]] == 0)  {int now=newnode();next[pre][s[i]] = now;pre = now;}else pre = next[pre][s[i]];}vis[pre] = id;}void build_ac_automation() {queue<int> que;fail[root] = root;for(int i=0; i<128; i++) {if(next[root][i] == 0) next[root][i] = root;else {fail[next[root][i]] = root;que.push(next[root][i]);}}while(!que.empty()) {int temp=que.front();que.pop();for(int i=0; i<128; i++)  {if(next[temp][i]==0) {next[temp][i] = next[fail[temp]][i];}else {fail[next[temp][i]] = next[fail[temp]][i];que.push(next[temp][i]);}}}}int flag[520];int query(char s[]) {int i,ans=0;memset(flag,0,sizeof(flag));int temp=root;for(i=0; s[i]; i++) {temp=next[temp][s[i]];int p = temp;while(p!=root) {if(vis[p]) {flag[vis[p]] = 1;ans++;}p = fail[p];}}return ans;}};node ac;int main() {int n,m,i,num=0;char s[210],str[10010];scanf("%d",&n);ac.init();for(i=1; i<=n; i++) {scanf("%s",s);ac.insert(s,i);}ac.build_ac_automation();scanf("%d",&m);for(i=0; i<m; i++) {scanf("%s",str);if(ac.query(str)) {printf("web %d:",i+1);num++;for(int j=0; j<520; j++) {if(ac.flag[j]) printf(" %d",j);}printf("\n");}}printf("total: %d\n",num);return 0;}



0 0
原创粉丝点击