最小堆的维护,POJ(2051)

题目链接:http://poj.org/problem?id=2051

///维持最小堆(优先队列)POJ2051
#include <iostream>
#include <string>

using namespace std;

struct Node {
    int Now;    ///出堆的时间
    int id;
    int p;  ///时间间隔
};

Node node [3001];
int K;  ///输出个数

void down (Node H[],int s,int m) {
    ///向下调整,s是要调整的编号,m是堆的size
    Node rc=H[s];
    for(int j=s*2; j<=m; j*=2) {
        if(j<m) {
            if(H[j].Now>H[j+1].Now) {   ///两个子节点中找到那个较小者
                j++;
            } else {
                ///如果相等,比较ID
                if(H[j].Now==H[j+1].Now&&(H[j].id>H[j+1].id))
                    j++;
            }
        }
        if(rc.Now<H[j].Now||(rc.Now==H[j].Now&&rc.id<H[j].id))
            break;
        H[s]=H[j];  ///更新子节点
        s=j;
    }
    H[s]=rc;    ///最后交换的子节点换上rc
}

///建立一个最小堆
void MakeMinHeap(Node H[],int length) {
    for(int i=length/2; i>0; --i)
        down(H,i,length);
}

int main() {
    string str;
    int i=1;
    cin>>str;
    while(str.compare("#")!=0) {
        cin>>node[i].id>>node[i].p;
        node[i].Now=node[i].p;
        i++;
        cin>>str;
    }
    int len=i-1;
    cin>>K;
    MakeMinHeap(node,len);
    for(int i=1; i<=K; i++) {
        cout<<node[1].id<<endl;
        node[1].Now+=node[1].p;
        down(node,1,len);   ///修改顶点后再次调整最小堆
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/TreeDream/p/5483412.html