poj 3630 || hdu 1671 Phone List (字典樹)

題目鏈接:   hdu 1671

題目大意:   給出幾串數組,是否存在一個串是另外一個串的前綴,是則輸出"YES"

解題思路:   每個字符爲單位建立一棵Trie樹

                  字符串結尾的結點用w標記,然後插入時判斷兩種情況:

                  每次插入時如果經過之前插入字符串的結尾,則之前插入的字符串必定是前綴

                  每次插入時如果插到結尾還在之前的結點中,則現在插入的字符串必定是前綴

                  字典樹的兩種寫法:

                  1.結點中包含next[ ],加快查找時間,但耗費大量的空間

                  2.結點中不包含next[ ],類似與建立有向圖利用pre[ ]遍歷,查找時間慢些,但省下很多空間

                  

代碼:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10100
struct snode{
    char ch1;
    int next,w;  //第二種寫法
}Tree[MAX*100];
char ch[20];
int pd,Index,pre[MAX*100];

void Add_edge(int a,char ch2,int len,int Tlen)  //建立有向圖
{
    Tree[Index].ch1=ch2,Tree[Index].next=pre[a];
    if(len==Tlen)
        Tree[Index].w=1;
    pre[a]=Index++;
}

void DFS(int Star,int len,int Tlen,int kk)   //DFS遍歷
{
    int i;
    if(len>Tlen||pd)
        return ;
    if(Tree[Star].w==1)
    {
        pd=1;
        return ;
    }
    for(i=pre[Star];i!=-1;i=Tree[i].next)
    {
        if(Tree[i].ch1==ch[len-1])   //遍歷之前插入的點
        {
            if(Tree[i].w==1)  //小對大
            {
                pd=1;
                return ;
            }
            if(len==Tlen)
            {
                pd=1;
                return ;
            }
            DFS(i,len+1,Tlen,kk);
            return ;
        }
    }
    if(Tree[Star].w&&i==-1&&kk!=1)   //找到結尾結點
    {
        pd=1;
        return;
    }
    Add_edge(Star,ch[len-1],len,Tlen);
    DFS(Index-1,len+1,Tlen,kk);
}

int main()
{
    int t,n,i;
    scanf("%d",&t);
    while(t--)
    {
        pd=0;
        Index=1;
        memset(pre,-1,sizeof(pre));
        memset(Tree,0,sizeof(Tree));
        Tree[0].ch1='\0';
        Tree[0].next=-1;
        Tree[0].w=0;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%s",ch);
            if(!pd)        //找到前綴則停止搜索
            {
                DFS(0,1,strlen(ch),i);
            }
        }
        if(pd)
            printf("NO\n");
        else
            printf("YES\n");
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章