Main topic: Connect K to point 22 for minimum length
Easy to pass, the optimal scheme, the connected office building must be taken adjacent to the next to be more superior
Then you can use greed to do the problem.
Before Czl to the great God learned to use heap to greedy practice Orz
The idea is to put all the initial segments into the heap.
Connect the shortest segment at a time, and Ans+=a[i]
Delete the current segment after the fetch, with the adjacent two segments, and then insert a new edge, the weight value is A[pre]+a[next]-a[now]
Its effect is a bit like the reverse arc in the maximum flow, the next time you take this edge, that is Ans+=a[pre]+a[next]-a[now]
Obviously A[now] with the previous offset, that is, do not take now, instead take the adjacent two side to go
1#include <stdio.h>2#include <string.h>3#include <algorithm>4#include <queue>5 using namespacestd;6 Const intMAXN =200020*2;7 structnode{8 intID;9 };TenPriority_queue<node>Q; One intPre[maxn],next[maxn],k,a[maxn],n; A BOOLDEL[MAXN]; - intTot,last,now,ans; - the BOOL operator<(node x, node Y) { - returnA[x.id]>A[y.id]; - } - + intMain () { -scanf"%d%d", &n, &k); +scanf"%d", &Last ); Atot=0; at for(intI=1; i<n; i++){ -scanf"%d", &Now ); -a[++tot]=now-Last ; -last=Now ; - } - for(intI=1; i<n; i++){ in Q.push (node) {i}); -pre[i]=i-1; next[i]=i+1; to } +pre[1]=next[tot]=0; -a[0]=1002000000;//Attention: cannot be maxlongint, because the back A[++tot] will explode the while(k--){ * while(! Q.empty () &&del[q.top (). Id]) Q.pop (); $ if(Q.empty ()) Break;Panax Notoginseng intNow=q.top (). ID; ans+=A[now]; Q.pop (); - the intL=pre[now],r=Next[now]; +del[now]=del[l]=del[r]=1; A thea[++tot]=a[l]+a[r]-A[now]; Q.push (node) {tot}); + -PRE[TOT]=PRE[L]; next[tot]=Next[r]; $ if(Pre[tot]) next[pre[tot]]=tot; $ if(Next[tot]) pre[next[tot]]=tot; - } -printf"%d\n", ans); the return 0; -}
BZOJ1150: [CTSC2007] Data backup backup--greedy + priority Queue maintenance heap