d

#include<iostream>
#include<string.h>
#include<stdio.h>
int mark[1002],link[1002],n;
char s[202][1020];
int g[202][202],s[202],t[202],lx[202],ly[202],link[202];
char temp[1002];
int min(int x,int y)
{
    return x>y?y:x;
}

void rev(int x,int len)
{
    int i,j;
    for(i=0,j=len-1;i<len;i++,j--)
        temp[j]=s[x][i];
}


void build()
{
    int i,j,len,k,count;
    for(i=0;i<n;i++)
        for(j=0;j<n;j++)
        {
            int len=strlen(s[i]);
            rev(i,len);
            count=0;
            for(k=0;temp[k]==s[j][k]&&k<len;k++)
                count++;
            g[i][j]=count;
        }
}

int dfs(int x)
{
    s[x]=1;
    for(i=0;i<n;i++)
    {
        if(lx[i]+ly[i]>=g[i][j]&&!t[i])
        {
            t[i]=1;
            if(link[i]==-1||dfs(link[i])
            {
                link[i]=x;
                return 1;
            }
        }
    }
    return 0;
}

void update()
{
    int a=1<<30;
    for(i=0;i<n;i++)
        if(s[i])
            for(j=0;j<n;j++)
                if(!t[i])
                    a=min(a,lx[i]+ly[i]-g[i][j]);
   for(i=0;i<n;i++)
   {
       if(s[i]) lx[i]-=a;
       if(t[i]) ly[i]+=a;
   }
}



void KM();
{
    for(i=0;i<n;i++)
    {
        lx[i]=ly[i]=0;
        for(j=0;j<n;j++)
            lx[i]=min(lx,g[i][j]);
    }
    memset(link,-1,sizeof(link));
    for(i=0;i<n;i++)
    {
        while(1)
        {
            memset(s,0,sizeof(s));
            memset(t,0,sizeof(t));
            if(dfs(i))
                break;
            else update();
        }
    }
}


int main()
{
    int i,j;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=0;i<n;i++)
            scanf("%s",s[i]);
        build();
        /*for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
                printf("%d",g[i][j]);
            printf("
");
        }*/
        KM();
        int ans=0;
        for(i=0;i<n;i+)
            ans+=(g[link[i][i]);
        printf("%d
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/assult/p/3264102.html