HDU 2896 病毒侵袭 AC自动机
来源:互联网 发布:2017年优化设计答案 编辑:程序博客网 时间:2024/06/14 02:43
思路:对每个字符串在Trie树上找一遍即可。
注意:理论应该有10w个节点,但是10w个MLE了,所以开8w也能过。
http://acm.hdu.edu.cn/showproblem.php?pid=2896
/********************************************* Problem : HDU 2896 Author : NMfloat InkTime (c) NM . All Rights Reserved .********************************************/#include <map>#include <set>#include <queue>#include <stack>#include <cmath>#include <ctime>#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#define rep(i,a,b) for(int i = (a) ; i <= (b) ; i ++) //遍历#define rrep(i,a,b) for(int i = (b) ; i >= (a) ; i --) //反向遍历#define repS(it,p) for(auto it = p.begin() ; it != p.end() ; it ++) //遍历一个STL容器#define repE(p,u) for(Edge * p = G[u].first ; p ; p = p -> next) //遍历u所连接的点#define cls(a,x) memset(a,x,sizeof(a))#define eps 1e-8using namespace std;const int MOD = 1e9+7;const int INF = 0x3f3f3f3f;typedef long long LL;typedef unsigned long long ULL;int T,n,m,k;int fx[] = {0,1,-1,0,0};int fy[] = {0,0,0,-1,1};const int MAXN = 80005;const int MAX_SIZE = 95;int tot ; char s[10005];int virus[4];//需要输出病毒的编号int recv[4];class AC_automation {private: struct Node { int next[MAX_SIZE]; //节点的儿子 int stat ; //有几个字符是以当前节点结尾的 }t[MAXN]; //Trie 树上的节点 int fail[MAXN]; //失配指针public: void init() { tot = 1; cls(t,0); cls(fail,0); } void reset_stat(int len) { rep(i,1,len) t[recv[i]].stat = virus[i]; } void insert(char * str,int idx) { int len = strlen(str) - 1; rep(i,0,len) str[i] -= ' ';//ascii 表可见字符,所以减掉一个空格 int pre = 0 , nxt = 0 ; rep(i,0,len) { nxt = t[pre].next[str[i]]; if(nxt == 0) { t[pre].next[str[i]] = tot ; nxt = tot ++; } pre = nxt; //printf("%d -> ",nxt); } //puts(""); t[nxt].stat = idx; //给每个字符串编号 } void get_fail() { queue<int>q; q.push(0); while(!q.empty()) { int u = q.front(); rep(i,0,MAX_SIZE-1) { if(t[u].next[i]) { q.push(t[u].next[i]); int tmp = u; while(fail[tmp]) { if(t[fail[tmp]].next[i]) { fail[t[u].next[i]] = t[fail[tmp]].next[i]; break; } tmp = fail[tmp]; } if(u != 0 && !fail[t[u].next[i]]) {//处理fail[tmp] = 0 时的情况 if(t[0].next[i]) fail[t[u].next[i]] = t[0].next[i]; } } } q.pop(); } //rep(i,1,tot-1) printf("%d %d %d\n",i,fail[i],t[i].stat); } int query(char * str) { int idx = 0; int len = strlen(str) - 1; rep(i,0,len) str[i] -= ' '; int now = 0; rep(i,0,len) { while(now && (!t[now].next[str[i]])) now = fail[now]; now = t[now].next[str[i]]; int tmp = now; while(tmp) { if(t[tmp].stat) { idx ++ ; virus[idx] = t[tmp].stat; recv[idx] = tmp; t[tmp].stat = 0; } tmp = fail[tmp]; } } return idx; }};AC_automation ac;void input() { char str[205]; ac.init(); getchar();//读掉一个回车 rep(i,1,n) { gets(str); ac.insert(str,i); } ac.get_fail();}void solve() { scanf("%d",&m); getchar(); int web_site; //有病毒网站的数目 int cnt = 0; rep(i,1,m) { gets(s); rep(i,1,3) virus[i] = 0; int len = ac.query(s); if(len > 0) { if(len >= 2) if(virus[1] > virus[2]) {swap(virus[1],virus[2]);swap(recv[1],recv[2]);} if(len >= 3) if(virus[2] > virus[3]) {swap(virus[3],virus[2]);swap(recv[3],recv[2]);} if(len >= 3) if(virus[1] > virus[2]) {swap(virus[1],virus[2]);swap(recv[1],recv[2]);} cnt ++; printf("web %d:",i); rep(i,1,len) printf(" %d",virus[i]); puts(""); } ac.reset_stat(len); } printf("total: %d\n",cnt);}int main(void) { //freopen("a.in","r",stdin); while(~scanf("%d",&n)) { input(); solve(); } return 0;}
0 0
- HDU 2896 病毒侵袭 (AC自动机)
- hdu 2896 病毒侵袭 //AC自动机
- HDU 2896:病毒侵袭(AC自动机)
- hdu 2896 病毒侵袭 AC自动机
- HDU 2896 病毒侵袭(AC自动机)
- hdu 2896 病毒侵袭 AC自动机基础
- HDU 2896 病毒侵袭 AC自动机
- hdu 2896 病毒侵袭 -- AC自动机
- hdu 2896 病毒侵袭 (AC自动机)
- HDU 2896 病毒侵袭(AC 自动机)
- HDU 2896 病毒侵袭 (AC自动机)
- HDU 2896 病毒侵袭 【AC自动机】
- hdu 2896 病毒侵袭 AC自动机
- [HDU 2896]病毒侵袭[AC自动机]
- hdu 2896 病毒侵袭(AC自动机)
- hdu 2896 病毒侵袭(AC自动机)
- hdu 2896 病毒侵袭 (AC自动机)
- hdu 2896 病毒侵袭(AC自动机)
- 233,自定义NSOperation
- HBase-2.HBase 的体系结构、行键、列族设计
- 堆排序算法的改进
- Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法
- HBase-3.HBase读数据和存储数据原理
- HDU 2896 病毒侵袭 AC自动机
- JavaSE入门学习11:Java面向对象之类和对象
- ConcurrentModificationException产生原因的情况解析
- HBase-4.HBase内部机制
- Weblogic创建域及相关参数调整
- 高斯模糊算法浅析-----------微信朋友圈的红包照片有感而发
- Python数据分析、展示
- 操作系统中作业、进程、线程、管程各自的定义及联系
- 学习闭包的一些发现2