AC 自动机模板题,输出路径。End数组记录路径。
#include <stdio.h>
#include <string.h>
#include <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;
}