POJ 3576 Hash Trie

来源:互联网 发布:mac os 10.10 cdr下载 编辑:程序博客网 时间:2024/05/05 10:36

POJ 3576
题目链接:
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16065
题意:
问怎样按照题目的规则得到最少的点(题意实在是无法描述)
思路:
首先知道Trie树能形成这些单词的字典树。然后就看树上有多少个子树可以合并。
所以问题转换成如何确定以某个点为根节点的子树的Hash值。
本题采用unsigned long long表示Hash值,如果溢出自动剔除高位。然而开脑洞测几种Hash方法,换一下常量就行了。
源码:

#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <iostream>#include <queue>using namespace std;#define ULL unsigned long long#define LL long long#define SEED 11198411const int MAXN = 150000;const int MAXM = 26;struct Trie{    int son[MAXN][MAXM];    int cnt, en[MAXN];    int root;    char cun[MAXN];    void init(){        root = 0;        cnt = 1;        memset(en, 0, sizeof(en));        memset(son, -1, sizeof(son));    }    void ins(char *str, int val)    {//        printf("str = %s\n", str);        int pos = root;        for(int i = 0 ; str[i] != '\0' ; i++){            int mark = str[i] - 'a';//            printf("mark = %d\n", mark);            if(son[pos][mark] == -1){                cun[cnt] = str[i];                son[pos][mark] = cnt++;            }            pos = son[pos][mark];            if(str[i + 1] == '\0')                en[pos] = val;        }//        printf("\n");    }}tree;struct Edge{    int deep;    int en;    ULL hash;}e[MAXN];int deep[MAXN];void dfs(int u){    e[u].deep = 0;    e[u].hash = 1;    e[u].en = tree.en[u];    LL t = 1;    for(int i = 0 ; i < 26 ; i++){        if(tree.son[u][i] != -1){            dfs(tree.son[u][i]);            e[u].deep = max(e[u].deep, e[tree.son[u][i]].deep);            e[u].hash = e[u].hash + (e[tree.son[u][i]].hash) * t + tree.cun[tree.son[u][i]] - 'a' + tree.en[tree.son[u][i]];        }        t *= 23;    }    e[u].deep++;//    printf("u = %d, deep = %d, hash = %I64u, en = %d, cun = %c\n", u, e[u].deep, e[u].hash, e[u].en, tree.cun[u]);}char str[35];bool cmp(Edge u, Edge v){    if(u.deep != v.deep)    return u.deep < v.deep;    if(u.hash != v.hash)    return u.hash < v.hash;    if(u.en != v.en)    return u.en < v.en;}int main(){//    freopen("POJ 3576.in", "r", stdin);    int n;    while(scanf("%d", &n) != EOF){        tree.init();        for(int i = 0 ; i < n ; i++){            scanf("%s", str);            tree.ins(str, 1);        }        dfs(0);        sort(e, e + tree.cnt, cmp);//        printf("tree.cnt = %d\n", tree.cnt);        int ans = 0;        for(int i = 1 ; i < tree.cnt ; i++){            if(e[i].hash != e[i - 1].hash || e[i].deep != e[i-1].deep || e[i].en != e[i-1].en)                ans++;        }        printf("%d\n", ans + 1);    }    return 0;}
0 0
原创粉丝点击