AGC028C - Min Cost Cycle 题解
题目链接:Min Cost Cycle
题目大意:洛谷
题解:远古时期写的题现在啥都不会了。
将\(A,B\)排序取前\(n\)个,对于每一个点\(00\)表示\(A,B\)都没有选,\(01\)表示\(A\)没选\(B\)选了,以此类推,所以有\(1\)恒比\(0\)小,所以考虑构造方案。
首先,每一个数的状态不外乎 4 个,如果有\(00\)或\(11\)的话可以将\(01,10\)串在一起,所以这种情况下可以直接输出前\(n\)个的和。
否则的话,判断能否构成环,如果不可以的话就往后找,找到几个来替换出\(00\)或\(11\)就可以了。
时间复杂度\(O(n\log n)\).
代码:
#include <set>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define Maxn 100000
set<pair<int,int> > st;
int a[Maxn+5],b[Maxn+5];
int x[Maxn+5];
int have[Maxn+5];
int mn(int a,int b){
return a<b?a:b;
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&a[i],&b[i]);
st.insert(make_pair(a[i],i<<1));
st.insert(make_pair(b[i],(i<<1)|1));
}
set<pair<int,int> >::iterator it;
int now=n,tmp;
it=st.begin();
ll sum=0;
while(now--){
tmp=(it->second)>>1;
sum+=(it->first);
if((it->second)&1){
x[tmp]+=1;
}
else{
x[tmp]+=2;
}
it++;
}
for(int i=1;i<=n;i++){
have[x[i]]++;
}
if(have[0]||(!have[2])||(!have[1])){
cout<<sum<<endl;
return 0;
}
if(((it->second)>>1)==tmp){
it--;
int now_1=(it->first);
it--;
int now_2=(it->first);
it++;
it++;
int now_3=(it->first);
it++;
int now_4=(it->first);
sum+=mn(now_3-now_2,now_4-now_1);
cout<<sum<<endl;
return 0;
}
it--;
x[tmp]=0;
sum-=(it->first);
it++;
while(it!=st.end()){
tmp=(it->second)>>1;
if(x[tmp]){
sum+=(it->first);
break;
}
it++;
}
cout<<sum<<endl;
return 0;
}
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。