• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-72  評論-126  文章-0  trackbacks-0
            http://acm.pku.edu.cn/JudgeOnline/problem?id=2054
            http://acm.hdu.edu.cn/showproblem.php?pid=1055
            好點經典的一道題目,做了半天都做不出來
            后來到網上看了解題報告才明白(解題報告網上有,我就不再出說明了)是n^2的算法
            我在想,每次都遍歷一遍找最大權值的點會不會太浪費時間,如果用堆取出權值最大的點效率就會有很大改進,變成n*log(n)了
            但是最大權值的父親節點也要從堆中取出,這有點麻煩
            結合昨天ZOJ月賽比賽中自創的可以取出任意節點的二叉堆,記錄位子來實現,想到了方法,多方試驗之后果然成功了
            在PKU提交也只用了16MS...哈哈
            貼出來曬曬
            #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;
            }

            下邊是n^2的算法,跑了200+MS。。簡潔是簡潔,但效率不高
            #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;
            }


            posted on 2009-06-29 16:30 shǎ崽 閱讀(1608) 評論(3)  編輯 收藏 引用

            評論:
            # re: hdu1055 & PKU2054------DP+可以任意取出節點的二叉堆 2009-06-30 11:10 | hhanger
            可以取出任意節點的二叉堆

            這個好像叫映射二叉堆。

            這個是不是可以直接用set來實現呢?  回復  更多評論
              
            # re: hdu1055 & PKU2054------DP+可以任意取出節點的二叉堆 2009-06-30 11:12 | hhanger
            發現變量名是hh,哈哈~~  回復  更多評論
              
            # re: hdu1055 & PKU2054------DP+可以任意取出節點的二叉堆 2009-07-02 13:04 | shǎ崽
            @hhanger
            哦,“映射二叉堆”原來已經有名字了的,哎呀,我孤陋寡聞了。。

            呵呵,我習慣把一些數組名都取做hh的,哈哈~~  回復  更多評論
              
            合区精品久久久中文字幕一区| 午夜精品久久久内射近拍高清| 国产欧美久久久精品影院| 国产精品九九久久免费视频 | 天天做夜夜做久久做狠狠| 波多野结衣中文字幕久久| 亚洲AV无码久久| 麻豆亚洲AV永久无码精品久久| 久久www免费人成看片| 久久免费看黄a级毛片| 久久婷婷国产剧情内射白浆| 久久综合偷偷噜噜噜色| 精品伊人久久大线蕉色首页| 亚洲中文字幕久久精品无码喷水| 久久久久久久久久久| 色欲av伊人久久大香线蕉影院| 少妇高潮惨叫久久久久久| 久久99国内精品自在现线| 嫩草影院久久国产精品| 蜜桃麻豆www久久国产精品| 99久久免费国产精品特黄| 人妻精品久久久久中文字幕69| 91久久精品91久久性色| 国内精品久久久久久久涩爱| 亚洲国产成人久久综合区| 久久久久亚洲AV无码专区体验| 久久99精品国产99久久6男男| 久久久久久久久久久免费精品| 老男人久久青草av高清| 99久久无码一区人妻a黑| 内射无码专区久久亚洲| 久久精品中文闷骚内射| 久久精品国产精品亚洲下载| 亚洲狠狠婷婷综合久久蜜芽 | 一级做a爰片久久毛片16| 久久免费99精品国产自在现线| 久久WWW免费人成一看片| 国产综合精品久久亚洲| 久久99精品久久久久子伦| 国产精品久久久久久久久软件| 久久电影网2021|