1. 程式人生 > >bzoj1150 [CTSC2007]數據備份

bzoj1150 [CTSC2007]數據備份

freopen 接下來 long long set 此外 推薦 open == script

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
 1
//It is made by wfj_2048~ 2 #include <algorithm> 3 #include <iostream> 4 #include <cstring> 5 #include <cstdlib> 6 #include <cstdio> 7 #include <vector> 8 #include <cmath> 9 #include <queue> 10 #include <stack> 11 #include <map> 12 #include <set> 13 #define inf (1<<30) 14 #define N (500010) 15 #define il inline 16 #define RG register 17 #define ll long long 18 19 using namespace std; 20 21 struct data{ 22 23 int x; ll val; 24 25 il bool operator < (const data &a) const{ 26 return val>a.val; 27 } 28 29 }; 30 31 priority_queue <data> Q; 32 33 int lst[N],nxt[N],del[N],n,k,tot; 34 ll dis[N],val[N],ans; 35 36 il int gi(){ 37 RG int x=0,q=1; RG char ch=getchar(); 38 while ((ch<0 || ch>9) && ch!=-) ch=getchar(); 39 if (ch==-) q=-1,ch=getchar(); 40 while (ch>=0 && ch<=9) x=x*10+ch-48,ch=getchar(); 41 return q*x; 42 } 43 44 int main(){ 45 #ifndef ONLINE_JUDGE 46 freopen("backup.in","r",stdin); 47 freopen("backup.out","w",stdout); 48 #endif 49 n=gi(),k=gi(),tot=n-1; 50 for (RG int i=1;i<=n;++i) dis[i]=gi(),lst[i]=i-1,nxt[i]=i+1; 51 for (RG int i=1;i<n;++i) Q.push((data){i,val[i]=dis[i+1]-dis[i]}); 52 nxt[n-1]=nxt[n]=0; 53 while (k--){ 54 while (del[Q.top().x]) Q.pop(); RG int x=Q.top().x; Q.pop(); 55 ans+=val[x],del[x]=del[lst[x]]=del[nxt[x]]=1; 56 if (!lst[x]) lst[nxt[nxt[x]]]=0; 57 else if (!nxt[x]) nxt[lst[lst[x]]]=0; else{ 58 val[++tot]=val[lst[x]]+val[nxt[x]]-val[x]; 59 lst[tot]=lst[lst[x]],nxt[tot]=nxt[nxt[x]]; 60 if (lst[tot]) nxt[lst[tot]]=tot; 61 if (nxt[tot]) lst[nxt[tot]]=tot; 62 Q.push((data){tot,val[tot]}); 63 } 64 } 65 printf("%lld\n",ans); return 0; 66 }

bzoj1150 [CTSC2007]數據備份