Description

  你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份。然而数据备份的工作是枯燥乏味的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏的乐趣。已知办公楼都位于同一条街上。你决定给这些办公楼配对(两个一组)。每一对办公楼可以通过在这两个建筑物之间铺设网络电缆使得它们可以互相备份。然而,网络电缆的费用很高。当地电信公司仅能为你提供 K 条网络电缆,这意味着你仅能为 K 对办公楼(或总计2K个办公楼)安排备份。任一个办公楼都属于唯一的配对组(换句话说,这 2K 个办公楼一定是相异的)。此外,电信公司需按网络电缆的长度(公里数)收费。因而,你需要选择这 K 对办公楼使得电缆的总长度尽可能短。换句话说,你需要选择这 K 对办公楼,使得每一对办公楼之间的距离之和(总距离)尽可能小。下面给出一个示例,假定你有 5 个客户,其办公楼都在一条街上,如下图所示。这 5 个办公楼分别位于距离大街起点 1km, 3km, 4km, 6km 和 12km 处。电信公司仅为你提供 K=2 条电缆。
  上例中最好的配对方案是将第 1 个和第 2 个办公楼相连,第 3 个和第 4 个办公楼相连。这样可按要求使用 K=2 条电缆。第 1 条电缆的长度是 3km-1km=2km ,第 2 条电缆的长度是 6km-4km=2km。这种配对方案需要总长 4km 的网络电缆,满足距离之和最小的要求。

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
 
正解:堆+链表模拟费用流。
很显然,只有相邻两点之间会有边,所以这是一个二分图的模型。
但是直接跑费用流会挂,所以我们考虑优化。
因为这个图比较简单,所以我们可以用堆+链表来模拟费用流。
我们每次在堆里取一条最短路,增广一条路以后,这条路会反过来,那么我们把它的相反数和它在链上的前后两点的路径值加起来,建一个新点丢到堆里就行了。
感觉讲起来很玄学。。还是推荐一个博客吧:http://www.cnblogs.com/GXZlegend/p/7128426.html
 
 //It is made by wfj_2048~
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define inf (1<<30)
#define N (500010)
#define il inline
#define RG register
#define ll long long using namespace std; struct data{ int x; ll val; il bool operator < (const data &a) const{
return val>a.val;
} }; priority_queue <data> Q; int lst[N],nxt[N],del[N],n,k,tot;
ll dis[N],val[N],ans; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} int main(){
#ifndef ONLINE_JUDGE
freopen("backup.in","r",stdin);
freopen("backup.out","w",stdout);
#endif
n=gi(),k=gi(),tot=n-;
for (RG int i=;i<=n;++i) dis[i]=gi(),lst[i]=i-,nxt[i]=i+;
for (RG int i=;i<n;++i) Q.push((data){i,val[i]=dis[i+]-dis[i]});
nxt[n-]=nxt[n]=;
while (k--){
while (del[Q.top().x]) Q.pop(); RG int x=Q.top().x; Q.pop();
ans+=val[x],del[x]=del[lst[x]]=del[nxt[x]]=;
if (!lst[x]) lst[nxt[nxt[x]]]=;
else if (!nxt[x]) nxt[lst[lst[x]]]=; else{
val[++tot]=val[lst[x]]+val[nxt[x]]-val[x];
lst[tot]=lst[lst[x]],nxt[tot]=nxt[nxt[x]];
if (lst[tot]) nxt[lst[tot]]=tot;
if (nxt[tot]) lst[nxt[tot]]=tot;
Q.push((data){tot,val[tot]});
}
}
printf("%lld\n",ans); return ;
}

bzoj1150 [CTSC2007]数据备份的更多相关文章

  1. BZOJ1150 [CTSC2007]数据备份Backup 链表+小根堆

    BZOJ1150 [CTSC2007]数据备份Backup 题意: 给定一个长度为\(n\)的数组,要求选\(k\)个数且两两不相邻,问最小值是多少 题解: 做一个小根堆,把所有值放进去,当选择一个值 ...

  2. bzoj1150 [CTSC2007]数据备份Backup 双向链表+堆

    [CTSC2007]数据备份Backup Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2727  Solved: 1099[Submit][Stat ...

  3. BZOJ1150[CTSC2007]数据备份Backup——模拟费用流+堆+链表

    题目描述 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游 ...

  4. BZOJ1150 [CTSC2007]数据备份Backup 【堆 + 链表】

    题目 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家中尽享计算机游戏的 ...

  5. BZOJ1150 [CTSC2007] 数据备份Backup 贪心_堆_神题

    Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设计一个系统让不同的办公楼彼此之间互相备份,而你则坐在家 ...

  6. BZOJ1150 [CTSC2007]数据备份Backup 贪心 堆

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1150 题意概括 数轴上面有一堆数字. 取出两个数字的代价是他们的距离. 现在要取出k对数,(一个数 ...

  7. bzoj1150: [CTSC2007]数据备份Backup--贪心+优先队列维护堆

    题目大意:将k对点两两相连,求最小长度 易证得,最优方案中,相连的办公楼一定是取相邻的比取不相邻的要更优 然后就可以用贪心来做这道题了.. 之前向CZL大神学习了用堆来贪心的做法orz 大概思路就是将 ...

  8. bzoj1150: [CTSC2007]数据备份Backup

    题目大意: 在n个点中,选出k对相邻的互不相同的点,使k段距离的总和最小. 贪心,双向链表. 首先,点之间的距离是动态的,所以要用堆来维护.   每次都选择最近的点.但因为其他情况,可能最终不会选择这 ...

  9. 【BZOJ1150】[CTSC2007]数据备份Backup 双向链表+堆(模拟费用流)

    [BZOJ1150][CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味的,因此 ...

随机推荐

  1. my.ini /etc/my.cnf jdbc url

    [client] default-character-set = utf8mb4 [mysql]# 设置mysql客户端默认字符集default-character-set=utf8mb4 [mysq ...

  2. 自动截取sql并合并,生成执行HQL

    ### 提取SQL语句 FILE_PATH="/data/SCRIPT" cat tables | while read file do echo "-----> ...

  3. Problem01 不死神兔

    题目:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子对数为多少? 程序分析:兔子的规律为数列1,1,2,3,5,8,13,21 ...

  4. Jmeter录制pc脚本

    1.打开jmeter后可以看到左边窗口有个“测试计划”和“工作台”,右键“测试计划”,添加 Threads(Users) →线程组,再右键 线程组→添加 配置元件→Http请求默认值 Http请求默认 ...

  5. Linux添加、创建新用户

    给Linux添加新用户,新建用户,新建帐号 添加用户组 sudo groupadd groupname 添加用户 sudo useradd username -m -s /bin/bash -d /h ...

  6. Murano Weekly Meeting 2015.09.29

    Meeting time: 2015.September.29th 1:00~2:00 Chairperson:  Serg Melikyan, PTL from Mirantis Meeting s ...

  7. eclipse中使用自带的git提交项目

    1.自带git插件进行配置我们的用户名和密码,即是自己github注册用户.windows--perferences--Team--Git--Configuration 2.eclipse生成SSH2 ...

  8. hduoj 2062Subset sequence

    Subset sequence Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  9. 报表XtraReport创建是实现

    1.创建XtraReport报表程序 一般设计这个程序是分着的,为了方便我就把他们合到一起 首先创建一个Winform Application 在form1中放一个button,右键程序,添加新项 如 ...

  10. Java中的阻塞队列-LinkedBlockingQueue(二)

    原文地址:http://benjaminwhx.com/2018/05/11/%E3%80%90%E7%BB%86%E8%B0%88Java%E5%B9%B6%E5%8F%91%E3%80%91%E8 ...