POJ 1699 KMP算法

View Code
  1 //Result:wizmann    1699    Accepted    732K    469MS    G++    1738B    2012-07-25 20:00:55
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <cstring>
  5 #include <iostream>
  6 #include <algorithm>
  7 #include <vector>
  8 #include <bitset>
  9 
 10 using namespace std;
 11 
 12 #define print(x) cout<<x<<endl
 13 #define input(x) cin>>x
 14 const int SIZE=12;
 15 const int INF=1<<30;
 16 
 17 struct node
 18 {
 19     int dest,val;
 20     node(){}
 21     node(int i_dest,int i_val)
 22     {
 23         dest=i_dest;val=i_val;
 24     }
 25 };
 26 
 27 char dna[SIZE][24];
 28 vector<node> g[SIZE];
 29 int next[SIZE][24];
 30 char visit[SIZE];
 31 
 32 int n;
 33 
 34 void kmp_get_next(int nr)
 35 {
 36     int len=strlen(dna[nr]);
 37     next[nr][0]=-1;
 38     for(int i=0,j=-1;i<len;i++,j++,next[nr][i]=j)
 39     {
 40         while(j>=0 and dna[nr][i]!=dna[nr][j]) j=next[nr][j];
 41     }
 42 }
 43 
 44 
 45 int kmp_do(int a,int b)
 46 {
 47     int i=0,j=0;
 48     int la=strlen(dna[a]);
 49     int lb=strlen(dna[b]);
 50     while(i<la) //<- This is the WA point
 51     {
 52         if(j==-1 or dna[a][i]==dna[b][j])
 53         {
 54             i++;j++;
 55         }
 56         else j=next[b][j];
 57     }
 58     /* 如果采用while(i<la and j<lb)的形式,如果b串有完美匹配,即ACCA与CC这种情况
 59      * 则循环自动跳出,不能做到“前辍后辍匹配”,所以只用while(i<la)判断
 60      * 
 61      * Noted by Moody _"Kuuy"_ Wizmann
 62      */
 63     return lb-j;
 64 }
 65 
 66 void makeG(int a,int b)
 67 {
 68     int k=kmp_do(a,b);
 69     g[a].push_back(node(b,k));
 70     //printf("%d -> %d (%d)\n",a,b,k);
 71 }
 72 
 73 int slove(int nr,int ok=0,int val=0)
 74 {
 75     if(ok==n-1) return val;
 76 
 77     int res=INF;
 78     visit[nr]=1;
 79     for(int i=0;i<(int)g[nr].size();i++)
 80     {
 81         node next=g[nr][i];
 82         if(!visit[next.dest])
 83         {
 84             res=min(res,slove(next.dest,ok+1,val+next.val));
 85         }
 86     }
 87     visit[nr]=0;
 88     return res;
 89 }
 90 
 91 int main()
 92 {
 93     int T;
 94     input(T);
 95     while(T--)
 96     {
 97         scanf("%d",&n);
 98         for(int i=0;i<n;i++)
 99         {
100             scanf("%s",dna[i]);
101             kmp_get_next(i);
102             g[i].clear();
103         }
104         for(int i=0;i<n;i++)
105         {
106             for(int j=0;j<n;j++) if(i!=j)
107             {
108                 makeG(i,j);
109             }
110         }
111         int ans=INF;
112         for(int i=0;i<n;i++)
113         {
114             memset(visit,0,sizeof(visit));
115             ans=min(ans,slove(i)+int(strlen(dna[i])));
116         }
117         printf("%d\n",ans);
118     }
119     return 0;
120 }

posted on 2012-07-25 20:06  Wizmann  阅读(215)  评论(0编辑  收藏  举报

导航