哈夫曼树+搜索
抄了抄代码
先开始不知道怎么限制哈夫曼树,然后看了看代码,是用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; }