题目链接:http://poj.org/problem?id=1699
扩展kmp求距离,随机算法求TSP问题。、
不过强度不给力啊,Age 取1024时跑了250ms,还多以WA结束,下面的跑了刚好1000ms >.<
Code:
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<time.h> #define M 24 #define Swap(x,y,t) {t=x,x=y,y=t;} const int N = 128; const int K = 64; const int KK = 48; const int Age = 4096; const int pm = 20; char s[16][M]; int l[16]; int map[16][16]; int n; int nxt[M],ext[M]; typedef struct talG{ int a[16]; int h; }Genetic; Genetic Memory[N]; Genetic *g[N]; typedef int (*CMP)(const void *,const void *); int Cmp(Genetic **a,Genetic **b) { return (*b)->h-(*a)->h; } int ExtendKmp(char s[],int ls,char t[],int lt) { int i,j,k; int Len,L; j=0; while(t[j+1]==t[j]&&j+1<lt) j++; nxt[1]=j,k=1; for(i=2;i<lt;i++){ Len=k+nxt[k],L=nxt[i-k]; if(Len>L+i) nxt[i]=L; else{ j=Len-i>0?Len-i:0; while(t[i+j]==t[j]&&i+j<lt) j++; nxt[i]=j,k=i; } } j=0; while(s[j]==t[j]&&j<lt&&j<ls) j++; ext[0]=j,k=0; for(i=1;i<ls;i++){ Len=k+ext[k],L=nxt[i-k]; if(Len>L+i) ext[i]=L; else{ j=Len-i>0?Len-i:0; while(s[i+j]==t[j]&&i+j<ls&&j<lt) j++; ext[i]=j,k=i; } } for(i=0;i<ls;i++){ if(i+ext[i]==ls) break; } return ls-i; } int H(int a[]) { int i,r=0; for(i=1;i<n;i++) r+=map[a[i-1]][a[i]]; return r; } void GeneticInit() { int i,j; int tmp; int a,b; for(i=0;i<N;i++){ g[i]=&Memory[i]; for(j=0;j<n;j++) Memory[i].a[j]=j; for(j=n;j;j--){ a=rand()%n; b=rand()%n; Swap(g[i]->a[a],g[i]->a[b],tmp); } g[i]->h=H(g[i]->a); } } void CrossOver(Genetic *g,Genetic *h) { int a[M],b[M]; int la,lb; int i,tmp; int low,up; low=rand()%n; up=rand()%n; for(la=lb=i=0;i<n;i++){ if(g->a[i]>=low&&g->a[i]<=up) a[la++]=i; if(h->a[i]>=low&&h->a[i]<=up) b[lb++]=i; } for(i=0;i<la&&i<lb;i++) Swap(g->a[a[i]],h->a[b[i]],tmp); } void Mutate(Genetic *g) { int tmp; int a,b; if(rand()%100<pm){ a=rand()%n; b=rand()%n; Swap(g->a[a],g->a[b],tmp); } } int GeneticRun() { //int r; int age; int i; srand(time(NULL)); GeneticInit(); for(age=0;age<Age;age++){ qsort(g,N,sizeof(g[0]),(CMP)Cmp); for(i=K;i<N;i+=2){ *g[i]=*g[rand()%K]; *g[i+1]=*g[rand()%K]; CrossOver(g[i],g[i+1]); } for(i=KK;i<N;i++){ Mutate(g[i]); g[i]->h=H(g[i]->a); } } return g[0]->h; } int main() { int t; int i,j,tot; scanf("%d",&t); while(t--){ scanf("%d",&n); for(tot=i=0;i<n;i++){ scanf("%s",s[i]); l[i]=strlen(s[i]); tot+=l[i]; } for(i=0;i<n;i++){ for(j=0;j<n;j++){ if(i!=j) map[i][j]=ExtendKmp(s[i],l[i],s[j],l[j]); } } tot-=GeneticRun(); printf("%d\n",tot); } return 0; }