标签:
输入的第一行包含整数n和k,其中n(2 ≤ n ≤100 000)表示办公楼的数目,k(1≤ k≤ n/2)表示可利用的网络电缆的数目。接下来的n行每行仅包含一个整数(0≤ s ≤1000 000 000), 表示每个办公楼到大街起点处的距离。这些整数将按照从小到大的顺序依次出现。
输出应由一个正整数组成,给出将2K个相异的办公楼连成k对所需的网络电缆的最小总长度。
上面的样例输入给出了前面描述的示例情形 对于每一个测试点,如果写到输出文件中的答案正确,则得到该测试点100%的分数,否则得零分。30%的输入数据满足n≤20。60%的输入数据满足n≤10 000。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<queue> 6 7 #define maxn 1000001 8 9 using namespace std; 10 11 int a[maxn*2],n,k,pre[maxn*2],next[maxn*2],num=0; 12 13 long long cha[maxn*2],ans=0; 14 15 bool vis[maxn*2]; 16 17 struct node{ 18 int x; 19 long long c; 20 bool operator <(const node &A)const{ 21 if(A.c==c)return x>A.x; 22 return c>A.c; 23 } 24 }; 25 26 priority_queue<node>q; 27 28 inline int in() 29 { 30 int x=0;char ch=getchar(); 31 while(ch<‘0‘||ch>‘9‘)ch=getchar(); 32 while(ch>=‘0‘&&ch<=‘9‘)x=x*10+ch-‘0‘,ch=getchar(); 33 return x; 34 } 35 36 void Pre() 37 { 38 for(int i=1;i<n;i++) 39 cha[i]=a[i+1]-a[i],q.push((node){i,a[i+1]-a[i]}),pre[i]=i-1,next[i]=i+1; 40 num=n; 41 pre[n]=n-1;next[0]=1; 42 } 43 44 void solve() 45 { 46 node Top; 47 for(int i=1;i<=k;i++) 48 { 49 Top=q.top();q.pop(); 50 while(vis[Top.x]) 51 Top=q.top(),q.pop(); 52 if(pre[Top.x]==0) 53 { 54 pre[next[next[Top.x]]]=0; 55 ans+=Top.c; 56 vis[Top.x]=vis[next[Top.x]]=1; 57 } 58 else if(next[Top.x]==n) 59 { 60 next[pre[pre[Top.x]]]=n; 61 ans+=Top.c; 62 vis[Top.x]=vis[pre[Top.x]]=1; 63 } 64 else 65 { 66 ans+=Top.c; 67 node New; 68 New.x=++num; 69 New.c=cha[pre[Top.x]]+cha[next[Top.x]]-Top.c; 70 pre[New.x]=pre[pre[Top.x]],next[pre[New.x]]=New.x; 71 next[New.x]=next[next[Top.x]],pre[next[New.x]]=New.x; 72 vis[Top.x]=vis[next[Top.x]]=vis[pre[Top.x]]=1; 73 cha[num]=New.c; 74 q.push(New); 75 } 76 } 77 } 78 79 int main() 80 { 81 n=in();k=in(); 82 for(int i=1;i<=n;i++)a[i]=in(); 83 Pre();solve(); 84 printf("%lld",ans); 85 return 0; 86 }
【链表】bzoj 1150: [CTSC2007]数据备份Backup
标签:
原文地址:http://www.cnblogs.com/tuigou/p/4868106.html