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;
}
posted @ 2020-09-09 10:31  with_hope  阅读(173)  评论(0编辑  收藏  举报