• <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不| 亚洲成色999久久网站| 国产亚洲成人久久| 久久99精品国产麻豆宅宅| 亚洲va久久久噜噜噜久久男同 | 久久无码人妻一区二区三区 | 亚洲国产成人精品女人久久久 | 久久青青草原精品影院| 国产国产成人精品久久| 久久线看观看精品香蕉国产| 9久久9久久精品| 好久久免费视频高清| 91精品国产色综久久| 99久久人人爽亚洲精品美女| 久久国产免费| 一级a性色生活片久久无少妇一级婬片免费放| 久久91精品综合国产首页| 青青久久精品国产免费看| 中文字幕精品久久| 性欧美大战久久久久久久久 | 久久99国产一区二区三区| 久久久久久一区国产精品| 性做久久久久久久久浪潮| 无码人妻久久一区二区三区| 久久香综合精品久久伊人| 国产真实乱对白精彩久久| 久久人人爽人人爽人人av东京热| 精品人妻伦九区久久AAA片69| 99久久免费国产特黄| 国产午夜精品久久久久九九| 久久无码AV一区二区三区| 99久久免费国产精精品| 久久久久久午夜精品| 国产成人综合久久综合| 久久久国产99久久国产一| 久久99精品综合国产首页| 国产精品一区二区久久精品涩爱| 久久精品国产精品国产精品污| 色天使久久综合网天天| 国产 亚洲 欧美 另类 久久| 色综合久久中文字幕无码|