LA4122

哈夫曼树+搜索

抄了抄代码

先开始不知道怎么限制哈夫曼树,然后看了看代码,是用bfs序来限制。因为每个节点的右子树节点肯定不小于左儿子,同一层也是。所以先搞出bfs序,然后搜索,判断每一层右边是否大于左边。

哈夫曼树的每个节点必然会有零个或两个儿子,这也是判断无解或有解的情况。

#include<bits/stdc++.h>
using namespace std;
const int N = 100010;
string s;
int n, cnt, ans, root, now, kase;
int child[N][2], val[N], pos[N];
vector<int> order;
void insert(int x)
{
    for(int i = 0; i < s.length(); ++i)
    {
        int t = s[i] - '0';
        if(!child[x][t])
            child[x][t] = ++cnt;
        x = child[x][t];    
    }
}
void dfs(int u)
{    
    if(pos[u] == order.size() - 1)
    {
        ++ans;
        return;
    }
    if(child[u][0] == 0)
    {
        dfs(order[pos[u] + 1]);
        return;
    }
    for(int i = 1; i * 2 <= val[u]; ++i)
    {
        val[child[u][0]] = i;
        val[child[u][1]] = val[u] - i;    
        if(val[order[pos[child[u][1]] - 1]] && val[order[pos[child[u][1]] - 1]] < val[child[u][1]]) continue;
        dfs(order[pos[u] + 1]);
    }
    val[child[u][0]] = val[child[u][1]] = 0;
}
bool build()
{
    for(int i = 1; i <= cnt; ++i) if(child[i][0] * child[i][1] == 0 && child[i][0] + child[i][1])
        return 0;
    queue<int> q;
    order.clear();
    q.push(1);
    while(!q.empty())
    {
        int u = q.front();
        q.pop();
        pos[u] = order.size();
        order.push_back(u);
        if(child[u][1]) q.push(child[u][1]);
        if(child[u][0]) q.push(child[u][0]);
    }    
    return true;
}
int main()
{
    while(cin >> n)
    {    
        if(!n)
            break;
        memset(child, 0, sizeof(child));
        ans = 0;
        cnt = 0;
        root = ++cnt;
        for(int i = 1; i <= n; ++i)
        {
            cin >> s;
            insert(root);
        }
        printf("Case %d: ", ++kase);
        if(!build())
        {
            puts("0");
            continue;
        }
        val[1] = 100;
        dfs(1);
        cout << ans << endl;
    }
    return 0;
}
View Code

 

posted @ 2017-07-10 10:11  19992147  阅读(148)  评论(0编辑  收藏  举报