hdu 1055 poj 2054 映射二叉堆
2013-05-10 19:23
260 查看
算法:
算法证明:http://hi.baidu.com/cheezer94/item/7b4a15214b2050022b0f1c0a
代码来源:http://www.cppblog.com/notonlysuccess/archive/2009/07/02/88793.html
ò 1.标记根节点为第一个访问的节点。
ò 2.求出当前未访问节点中的最大点权节点i。
ò 3.将i和它的父亲j合并为一个节点,节点权值为两者权值的算术平均数。在序列P中将j的后继置为i。同时更新树的信息。
ò 4.若当前树中节点数大于1,则转第2步。
ò 5.树的大小为1时算法结束。
ò 6.扫描求得的P序列得到答案。
ò 时间复杂度:O(N^2)。期望得分50-70分。
(使用映射二叉堆)
ò 注意到我们每次操作需要得到当前最大权对应的节点i并将i的儿子的父亲改为i的父亲。
ò O(N)的扫描成为算法复杂度的瓶颈。
ò 如何高效求最大值?
ò 推荐数据结构:最大堆(O(LogN))。
ò 如何高效地将i的儿子的父亲改为i的父亲?
ò 推荐数据结构:并查集(O(α(N)))。
ò 总的时间复杂度:O(NLogN)。期望得分100分。
注意根不能放到堆中!
算法证明:http://hi.baidu.com/cheezer94/item/7b4a15214b2050022b0f1c0a
代码来源:http://www.cppblog.com/notonlysuccess/archive/2009/07/02/88793.html
ò 1.标记根节点为第一个访问的节点。
ò 2.求出当前未访问节点中的最大点权节点i。
ò 3.将i和它的父亲j合并为一个节点,节点权值为两者权值的算术平均数。在序列P中将j的后继置为i。同时更新树的信息。
ò 4.若当前树中节点数大于1,则转第2步。
ò 5.树的大小为1时算法结束。
ò 6.扫描求得的P序列得到答案。
ò 时间复杂度:O(N^2)。期望得分50-70分。
#include "stdio.h" #include "string" #define maxn 1001 struct H{ int val; int cost; int time; void clear() { val = cost = time = 0; } }hh[maxn]; int father[maxn]; int main() { int n,r,i; while(scanf("%d%d",&n,&r),n+r) { for(i =1 ; i <= n ; i ++) { scanf("%d",&hh[i].cost); hh[i].val = hh[i].cost; hh[i].time = 1; } for(i = 1; i < n ; i ++) { int a,b; scanf("%d%d",&a,&b); father[b] = a; } while(true) { int idx = 0; for(i = 1 ; i <= n ; i ++) { if(i != r && hh[i].time && (idx == 0 || hh[idx].val * hh[i].time < hh[i].val * hh[idx].time)) { idx = i; } } if(idx == 0) break; int f = father[idx]; hh[f].cost += hh[idx].cost + hh[idx].val * hh[f].time; hh[f].val += hh[idx].val; hh[f].time += hh[idx].time; hh[idx].clear(); } printf("%d\n",hh[r].cost); } return 0; }
(使用映射二叉堆)
ò 注意到我们每次操作需要得到当前最大权对应的节点i并将i的儿子的父亲改为i的父亲。
ò O(N)的扫描成为算法复杂度的瓶颈。
ò 如何高效求最大值?
ò 推荐数据结构:最大堆(O(LogN))。
ò 如何高效地将i的儿子的父亲改为i的父亲?
ò 推荐数据结构:并查集(O(α(N)))。
ò 总的时间复杂度:O(NLogN)。期望得分100分。
注意根不能放到堆中!
#include "stdio.h" #include "string" #define maxn 1001 //-----------------------Binary Heap------------------------------------ struct Heap { int val,cost,time,idx; }hh[maxn]; int pos[maxn]; int len; bool Prior(Heap a,Heap b) { return a.val * b.time > b.val * a.time; } void Push(Heap s) { int i; for(i = ++len ; i > 1 && Prior(s,hh[i/2]); i /= 2) { hh[i] = hh[i/2]; pos[hh[i].idx] = i; } hh[i] = s; pos[hh[i].idx] = i; } Heap Pop(int idx) { if(idx == -1) return hh[0]; Heap ret = hh[idx]; Heap last = hh[len--]; int i,s; for(i = idx ; i * 2 <= len; i = s) { s = i * 2; if(s + 1 <= len && Prior(hh[s+1],hh[s])) { s ++; } if(Prior(hh[s],last)) { hh[i] = hh[s]; pos[hh[i].idx] = i; } else { break; } } hh[i] = last; pos[hh[i].idx] = i; for(i = idx ; i > 1 && Prior(hh[i],hh[i/2]); i /= 2) { Heap buf = hh[i]; hh[i] = hh[i/2]; hh[i/2] = buf; pos[hh[i].idx] = i; pos[hh[i/2].idx] = i/2; } return ret; } //--------------------------------------------------------------- int father[maxn]; int main() { int n,r,i; hh[0].cost = hh[0].time = hh[0].val = 0; while(scanf("%d%d",&n,&r),n+r) { len = 0; Heap root; for(i =1 ; i <= n ; i ++) { Heap buf; scanf("%d",&buf.cost); buf.val = buf.cost; buf.time = 1; buf.idx = i; if(i == r) { root = buf; } else { Push(buf); } } for(i = 1 ; i < n ; i ++) { int a,b; scanf("%d%d",&a,&b); father[b] = a; } while(len) { Heap max = Pop(1); int f = father[max.idx]; if(f == r) { root.cost += max.cost + max.val * root.time; root.time += max.time; root.val += max.val; } else { Heap fa = Pop(pos[f]); fa.cost += max.cost + max.val * fa.time; fa.time += max.time; fa.val += max.val; fa.idx = f; Push(fa); } pos[max.idx] = -1; } printf("%d\n",root.cost); } return 0; }
相关文章推荐
- HDU_1055 && POJ_2054 Color a Tree(贪心)
- hdu 1055 & poj 2054 Color a Tree 树&贪心 找最大费用点和父节点合并
- POJ 2054 && HDOJ 1055
- 二叉堆模板小结-附上解题报告poj3253、poj2442、poj2010、poj3481
- HDU 1159 & POJ 1458 Common Subsequence (LCS)
- Investment(POJ-2063 && HDU-1963)
- HDU 1671 & POJ 3630 Phone List(字典树基础题)
- hdu 2054 A == B ?
- HDU 2053a/b + c/d 2054 又见gcd
- HDU-1501 (POJ-2192) Zipper (DFS||DP)
- HDU 1541 & POJ 2352 Stars (树状数组)
- 最小(大)生成树_裸题(HDU-1863,POJ-2377)
- hdu 1081 & poj 1050 To The Max(最大和的子矩阵)
- 各种最小生成树。 HDU 1863 HDU 1301 POJ 1258
- HDU_2112 HDU Today(DIjkstra + map映射)
- [ACM] HDU 2054 A == B?
- 2013_CSUST_3_23校内训练赛第一场【old】【hdu 3496、2191、4508、4506、2181 POJ 3264 3210 3094】
- 计算几何基础与应用:HDU 1348&&ZOJ 1648&&POJ 2398&&ZOJ 1010
- poj 1151 && hdu 1542
- HDU 2054 A == B 【String 的骚操作 , string find 的应用】