标签:i+1 lan i++ div ras problem 设置 pair erase
# 题意
给定n个位置(距离原点),每个位置上有一个公司,k表示可以用的网线数量,每个网线将连接两个公司且每一个公司只能连接一个网线,求满足k对配对情况下,所有电缆长度的最小值。
# 题解
最小值两边的距离要么不选,要么同时选,因为选了最小值就不能选旁边的所以每次选择最小的,并把最小的两边的和减去最小的加入到集合之中,因为两者相加即除了最小值的两边,并且当前的当要在最小值外选扩展另一条边的时候d[i-1] + d[i+1] -d[i] 正好能表示两条边的时候会增加的值,将这个入堆,不断选最小值并执行当前的操作最后就是最优值,因为d[i-1]和d[i+1]有边界的问题所以设置边界为值域内的无穷大,保证永远不会作为选择被选
1 #include <bits/stdc++.h> 2 #define pli pair<long long ,int> 3 using namespace std; 4 const int N=1e5+10; 5 long long d[N]; 6 int l[N],r[N]; 7 int n,k; 8 void move_node(int i){ 9 r[l[i]]=r[i]; 10 l[r[i]]=l[i]; 11 } 12 int main(){ 13 cin>>n>>k; 14 set<pli>s; 15 for(int i=1;i<=n;i++) 16 cin>>d[i]; 17 for(int i=n;i>=1;i--) 18 d[i]-=d[i-1]; 19 20 d[1]=d[n+1]=INT_MAX; 21 for(int i=1;i<=n+1;i++){ 22 l[i]=i-1; 23 r[i]=i+1; 24 s.insert({d[i],i}); 25 } 26 long long ans=0; 27 28 while(k--) { 29 auto t=s.begin(); 30 long long a=t->first; 31 int p = t->second,left=l[p],right=r[p]; 32 s.erase(t); 33 s.erase({d[left],left}),s.erase({d[right],right}); 34 move_node(left),move_node(right); 35 ans+=a; 36 d[p]=d[left]+d[right]-d[p]; 37 s.insert({d[p],p}); 38 } 39 cout<<ans; 40 }
标签:i+1 lan i++ div ras problem 设置 pair erase
原文地址:https://www.cnblogs.com/hhyx/p/12536318.html