DFA自动机.....

http://unbelievable.ycool.com/post.715479.html

 

 

DFA是用来做多串匹配的....  详情还是要看IOI2004ZZY的论文拉....
反正是个很拽很拽的算法拉!!!

我好不容易写了个标程出来....狂兴奋啊......
// 其实这就是05-06-10-4 拉......

{$R-,I-,Q-,S-}
program meteor;
const inf='meteor.in';
     ouf='meteor.out';
     maxn=500000;
     maxl=100000;
type nodetype=record
               child:array ['a'..'z'] of longint;
               prefix,num:longint;
               been:boolean;
             end;
    nodest=array [1..maxn] of longint;
    node=array [1..maxl] of char;
var dfa:array [0..maxn] of nodetype;
   ed:array [0..maxl] of longint;
   s:node;
   sp,n,m:longint;

procedure build(k:longint);
var i,a:longint;
   temp:char;
begin
 a:=1;
 repeat
   read(temp);
   if dfa[a].child[temp]=0 then begin
     inc(sp); inc(dfa[a].num);
     dfa[a].child[temp]:=sp;
   end;
   a:=dfa[a].child[temp];
 until eoln;
 readln;
 ed[k]:=a;
end;

procedure init;
var i:longint;
begin
 assign(input,inf);reset(input);
 readln(n);
 for i:=1 to n do read(s[I]);
 readln;
 fillchar(dfa,sizeof(dfa),0);
 sp:=1; dfa[1].been:=false;
 readln(m);
 for i:=1 to m do
   build(i);
 close(input);
end;

procedure makeprefix;
var temp,h,t,k:longint;
   st:nodest;
   i:char;
begin
 fillchar(st,sizeof(st),0);
 for i:='a' to 'z' do dfa[0].child[I]:=1;
 h:=0; t:=1; st[1]:=1; dfa[1].prefix:=0;
 repeat
   inc(h); temp:=dfa[st[h]].num;
   for i:='a' to 'z' do begin
     if temp=0 then break;
     if dfa[st[h]].child[I]<>0 then begin
       inc(t); st[t]:=dfa[st[h]].child[I]; dec(temp);
       k:=dfa[st[h]].prefix;
       while dfa[k].child[I]=0 do
         k:=dfa[k].prefix;
       dfa[st[t]].prefix:=dfa[k].child[I];
     end;
   end;
 until h=t;
end;

procedure work;
var i,k:longint;
   t:char;
begin
 dfa[1].been:=true;
 k:=1;
 for i:=1 to n do begin
   while dfa[k].child[s[I]]=0 do
     k:=dfa[k].prefix;
   k:=dfa[k].child[s[I]];
   dfa[k].been:=true;
 end;
end;

procedure out;
var i:longint;
begin
 assign(output,ouf);rewrite(output);
 for i:=1 to m do
   if dfa[ed[I]].been then writeln('YES') else writeln('NO');
 close(output);
end;

procedure check(k:longint);
begin
 k:=dfa[k].prefix;
 while not dfa[k].been do begin
   dfa[k].been:=true;
   k:=dfa[k].prefix;
 end;
end;

procedure dfs(k:longint);
var i:char;
begin
 if k=0 then exit;
 if dfa[k].been then check(k);
 if dfa[k].num=0 then exit;
 for i:='a' to 'z' do
   if dfa[k].child[I]>0 then dfs(dfa[k].child[I]);
end;

begin
 init;
 makeprefix;
 work;
 dfs(1);
 out;
end.


 

posted @ 2008-12-05 15:25  jesonpeng  阅读(308)  评论(0编辑  收藏  举报