hdu2144 Evolution (LCS+并查集)

给定N个物种的基因序列,若俩个序列s1和s2的最长公共子串长度len满足 |s1|*p<len && |s2|*p<len (p是题目给定的百分比),则俩个物种属于同一类,问这N个物种可以分为几类

分析:额,LCS+并查集

View Code
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
const int N = 100+10;
int n,f[N];
double p;
char str[N][N];
void init()
{
    for(int i=0;i<n;i++)
        f[i]=i;
}
int find(int x)
{
    if(x==f[x])
        return f[x];
    f[x]=find(f[x]);
    return f[x];
}
int LCS(const char *str1,const char *str2)
{    
    int xlen=strlen(str1);       //横向长度   
    int tmp[N]={0};            //保存矩阵的上一行    
    int arr[N]={0};    //当前行  
    int ylen=strlen(str2);       //纵向长度 
    int maxele=0;               //矩阵元素中的最大值   
    int pos=0;                  //矩阵元素最大值出现在第几列  
    for(int i=0;i<xlen;i++)
    {         
        for(int j=0;j<ylen;j++)
        {     
            arr[j]=0;
            if(str1[i]==str2[j])
            {          
                if(j==0)       
                    arr[j]=1;    
                else          
                    arr[j]=tmp[j-1]+1;  
                if(arr[j]>maxele)
                {      
                    maxele=arr[j];    
                    pos=j;      
                }     
            }       
        }
        for(int j=0;j<ylen;j++)
            tmp[j]=arr[j];
    }  
    return maxele;
}
int main()
{
    int cas=0;
    while(scanf("%d %lf",&n,&p)==2)
    {
        init();
        for(int i=0;i<n;i++)
            scanf("%s",str[i]);
        for(int i=0;i<n;i++)
        {    
            int a=find(i);
            int len1=strlen(str[i]);
            for(int j=i+1;j<n;j++)
            {
                int b=find(j);
                if(a==b)//若已经属于同一类了,就不需要求了
                    continue;
                int len=LCS(str[i],str[j]);
                int len2=strlen(str[j]);
                if(len1*p*0.01<len && len2*p*0.01<len)
                    f[b]=a;
            }
        }
        int ans=0;
        for(int i=0;i<n;i++)
        {
            if(i==find(i))
                ans++;
        }
        printf("Case %d:\n%d\n",++cas,ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/nanke/p/2439440.html