UVA 11488 Hyper Prefix Sets(trie的应用)

题目大意:给你 n 个字符串,然后让你找出其中的一个集合 S,设 P(S)为S集合中所有字符串的公共前缀长度*字符串个数,让你求出
P的最大值。
思路:因为是前缀的问题,可以想到用 trie 。把字符串全都插进去,然后扫描每个节点,那么就是所有的P,该节点的P = 它到根节点的
距离*经过这个节点的字符串个数,找出最大值即可。思路是有了,可是这道题还有一个地方,那就是空间问题,算一下是 10^8 ,但 UVA
好像不考虑空间来着,这么大的数组,我竟然过了。。 = = ,其实应该是MLE的,那怎么办呢,写 trie 的指针形式呗!

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

const int MAX_NODE = 50000*201;
const int SIGMA_SIZE = 2;

int ans;

struct Node
{
    Node* ch[SIGMA_SIZE];
    int val;
    Node()
    {
        ch[0] = NULL;
        ch[1] = NULL;
        val = 0;
    }
};

struct Trie
{
    Node *root;
    void init()
    {
        root = new Node();
    }

    int idx(char c)
    {
        return c - '0';
    }

    void insert(char *s)
    {
        Node* u = root;
        int len = strlen(s);
        for(int i = 0;i < len;i++)
        {
            int c = idx(s[i]);
            if(u->ch[c] == NULL)
            {

                u->ch[c] = new Node();
            }
            u = u->ch[c];
            u->val++;
        }

    }

    void solve(Node* u,int len)
    {
        ans = max(ans,len*(u->val));
        for(int i = 0;i < SIGMA_SIZE;i++)
        {
            if(u->ch[i])
                solve(u->ch[i],len+1);
        }
        delete u;
    }
}trie;

char str[222];

int main()
{
    int _;
    scanf("%d",&_);
    while(_--)
    {
        trie.init();
        int n;
        scanf("%d",&n);
        for(int i = 0;i < n;i++)
        {
            scanf("%s",str);
            trie.insert(str);
        }
        ans = 0;
        trie.solve(trie.root,0);
        printf("%d\n",ans);
    }
    return 0;
}


你可能感兴趣的:(UVA 11488 Hyper Prefix Sets(trie的应用))