hdu 2896
2015-08-16 20:02
369 查看
AC 自动机模板题,输出路径。End数组记录路径。
#include <stdio.h>
#include <string.h>
#incl
4000
ude <algorithm>
#include <queue>
#pragma warning (disable :4996)
using namespace std;
const int Max = 210 * 505;
int Next[Max][128], Fail[Max], End[Max];
int root, L;
int Newnode()
{
for (int i = 0; i < 128; i++)
Next[L][i] = -1;
End[L++] = -1;
return L - 1;
}
void Init()
{
L = 0;
root = Newnode();
}
void Insert(char buf[], int id)
{
int len = strlen(buf);
int now = root;
for (int i = 0; i < len; i++)
{
if (Next[now][buf[i]] == -1)
Next[now][buf[i]] = Newnode();
now = Next[now][buf[i]];
}
End[now] = id;
}
void Build()
{
Fail[root] = root;
queue<int>Q;
for (int i = 0; i < 128; i++)
if (Next[root][i] == -1)
Next[root][i] = root;
else
{
Fail[Next[root][i]] = root;
Q.push(Next[root][i]);
}
while (!Q.empty())
{
int now = Q.front();
Q.pop();
for (int i = 0; i < 128; i++)
{
if (Next[now][i] == -1)
Next[now][i] = Next[Fail[now]][i];
else
{
Fail[Next[now][i]] = Next[Fail[now]][i];
Q.push(Next[now][i]);
}
}
}
}
bool used[510];
bool Query(char buf[], int n, int id)
{
int len = strlen(buf);
int now = root;
memset(used, false, sizeof(used));
bool flag = false;
for (int i = 0; i < len; i++)
{
now = Next[now][buf[i]];
int temp = now;
while (temp != root)
{
if (End[temp] != -1)
{
used[End[temp]] = true;
flag = true;
}
temp = Fail[temp];
}
}
if (!flag)return false;
printf("web %d:", id);
for (int i = 1; i <= n; i++)
if (used[i])
printf(" %d", i);
printf("\n");
return true;
}
char buf[Max];
int main()
{
int m, n;
while (~scanf("%d", &n))
{
Init();
for (int i = 1; i <= n; i++)
{
scanf("%s", buf);
Insert(buf, i);
}
Build();
scanf("%d", &m);
int ans = 0;
for (int i = 1; i <= m; i++)
{
scanf("%s", buf);
if (Query(buf, n, i))
ans++;
}
printf("total: %d\n", ans);
}
return 0;
}
#include <stdio.h>
#include <string.h>
#incl
4000
ude <algorithm>
#include <queue>
#pragma warning (disable :4996)
using namespace std;
const int Max = 210 * 505;
int Next[Max][128], Fail[Max], End[Max];
int root, L;
int Newnode()
{
for (int i = 0; i < 128; i++)
Next[L][i] = -1;
End[L++] = -1;
return L - 1;
}
void Init()
{
L = 0;
root = Newnode();
}
void Insert(char buf[], int id)
{
int len = strlen(buf);
int now = root;
for (int i = 0; i < len; i++)
{
if (Next[now][buf[i]] == -1)
Next[now][buf[i]] = Newnode();
now = Next[now][buf[i]];
}
End[now] = id;
}
void Build()
{
Fail[root] = root;
queue<int>Q;
for (int i = 0; i < 128; i++)
if (Next[root][i] == -1)
Next[root][i] = root;
else
{
Fail[Next[root][i]] = root;
Q.push(Next[root][i]);
}
while (!Q.empty())
{
int now = Q.front();
Q.pop();
for (int i = 0; i < 128; i++)
{
if (Next[now][i] == -1)
Next[now][i] = Next[Fail[now]][i];
else
{
Fail[Next[now][i]] = Next[Fail[now]][i];
Q.push(Next[now][i]);
}
}
}
}
bool used[510];
bool Query(char buf[], int n, int id)
{
int len = strlen(buf);
int now = root;
memset(used, false, sizeof(used));
bool flag = false;
for (int i = 0; i < len; i++)
{
now = Next[now][buf[i]];
int temp = now;
while (temp != root)
{
if (End[temp] != -1)
{
used[End[temp]] = true;
flag = true;
}
temp = Fail[temp];
}
}
if (!flag)return false;
printf("web %d:", id);
for (int i = 1; i <= n; i++)
if (used[i])
printf(" %d", i);
printf("\n");
return true;
}
char buf[Max];
int main()
{
int m, n;
while (~scanf("%d", &n))
{
Init();
for (int i = 1; i <= n; i++)
{
scanf("%s", buf);
Insert(buf, i);
}
Build();
scanf("%d", &m);
int ans = 0;
for (int i = 1; i <= m; i++)
{
scanf("%s", buf);
if (Query(buf, n, i))
ans++;
}
printf("total: %d\n", ans);
}
return 0;
}
相关文章推荐
- 让linux每天定时备份MySQL数据库并删除五天前的备份文件
- 20个高级Java面试题汇总
- hibernate之增删改查demo
- 《Java设计模式》之外观模式
- 回溯--迷宫问题
- 【译】Android主题动态切换开源库Prism基本原理1-核心库
- 总结篇(1)——机房收费系统
- 9个Java初始化和回收的面试题
- 存储过程
- java面向对象程序设计:对象
- 清华建筑系毕业生工作8年后心得总结
- 写出高性价比代码之C#建议第52-及时释放资源
- Gym - 100637A Nano alarm-clocks 模拟
- HDU 1060 Leftmost Digit(数学)
- linux中文件搜索相关的locate,find,whereis与which,grep的使用
- ZOJ 1654 Place the Robots (二分匹配 )
- sizeof 操作符详解
- Linux Makefile 详细语法
- 【后缀自动机】 BZOJ 3926 ZJOI2015 诸神眷顾的幻想乡
- 机房收费系统--充值