题目链接: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;
}