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 }

你可能感兴趣的:(poj)