Review-堆(Bzoj1150)

来源:互联网 发布:tick高频交易算法 编辑:程序博客网 时间:2024/06/10 01:30

1150: [CTSC2007]数据备份Backup

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 758  Solved: 317
[Submit][Status]

Description

 

Input

输入的第一行包含整数n和k,其中n(2 ≤ n ≤100 000)表示办公楼的数目,k(1≤ k≤ n/2)表示可利用的网络电缆的数目。接下来的n行每行仅包含一个整数(0≤ s ≤1000 000 000), 表示每个办公楼到大街起点处的距离。这些整数将按照从小到大的顺序依次出现。

Output

输出应由一个正整数组成,给出将2K个相异的办公楼连成k对所需的网络电缆的最小总长度。

Sample Input

5 2
1
3
4
6
12

Sample Output

4

HINT

上面的样例输入给出了前面描述的示例情形 对于每一个测试点,如果写到输出文件中的答案正确,则得到该测试点100%的分数,否则得零分。30%的输入数据满足n≤20。60%的输入数据满足n≤10 000。


题解: 

首先要推出相邻的是最短的,但是相邻有种情况如样例:当你选取四个点中间两个点时,这两个点的距离加上两边的点之间的距离大于左边两点之间的距离与右边两点的距离,所以处理问题在用堆取出最小值(中间两点)要将左边两点和右边两点的距离和加入堆中,为了更好的表示取左边两个和右边两点时的情况,加入的是距离和减去中间两点的距离,这样加入后就将加入中间两点的距离消去。


代码:

program pro;type heap=record pr,po:longint; end;var    he:array[-1..100]of heap;    pos,ne,pre:array[-1..100050]of longint;    lo:array[0..100050]of longint;    ans,tot,n,m:longint;procedure swap(var x,y:longint);var    k:longint;begin    k:=x; x:=y; y:=k;end;procedure pushup(x:longint);begin    while (he[x].pr<he[x shr 1].pr) do    begin        pos[he[x shr 1].po]:=x;        swap(he[x].pr,he[x shr 1].pr);        swap(he[x].po,he[x shr 1].po);        x:=x shr 1;    end;    pos[he[x].po]:=x;end;procedure pushdown(x:longint);var    tmp:longint;begin    while (x shl 1<=tot) do    begin        tmp:=x shl 1;        if (tmp<tot)and(he[tmp].pr>he[tmp+1].pr) then inc(tmp);        if (he[x].pr>he[tmp].pr) then        begin            pos[he[tmp].po]:=x;            swap(he[x].pr,he[tmp].pr);            swap(he[x].po,he[tmp].po);            x:=tmp;        end        else break;    end;    pos[he[x].po]:=x;end;procedure push(x,y:longint);begin    inc(tot);    he[tot].pr:=x; he[tot].po:=y; pos[y]:=tot;    pushup(tot);end;procedure delete(x:longint);begin    he[x].pr:=maxlongint;    pushdown(x);end;procedure init;var    i:longint;begin    readln(n,m);    for i:=1 to n do readln(lo[i]);    for i:=2 to n do    begin        pre[i]:=i-1; ne[i]:=i+1;        push(lo[i]-lo[i-1],i);    end;    pre[2]:=-1; ne[n]:=-1;end;procedure main;var    i,j,a,b:longint;k:heap;begin        init;        for i:=1 to m do        begink.pr:=he[1].pr; k.po:=he[1].po;   if pre[k.po]=-1 then           begin                inc(ans,k.pr);                delete(1); delete(pos[ne[k.po]]);                pre[ne[ne[k.po]]]:=-1;           end           else           if ne[k.po]=-1 then           begin                inc(ans,k.pr);                delete(1); delete(pos[pre[k.po]]);                ne[pre[pre[k.po]]]:=-1;           end           else           begin                inc(ans,k.pr);                a:=ne[k.po]; b:=pre[k.po];                pre[k.po]:=pre[b]; ne[pre[b]]:=k.po;ne[k.po]:=ne[a]; pre[ne[a]]:=k.po;he[1].pr:=he[pos[a]].pr+he[pos[b]].pr-he[1].pr;                pushdown(1);                delete(pos[a]); delete(pos[b]);           end;        end;        writeln(ans);end;begin    main;end.




0 0
原创粉丝点击