AGC028C

题目链接:Min Cost Cycle

题目大意:洛谷


题解:远古时期写的题现在啥都不会了。

(A,B)排序取前(n)个,对于每一个点(00)表示(A,B)都没有选,(01)表示(A)没选(B)选了,以此类推,所以有(1)恒比(0)小,所以考虑构造方案。

首先,每一个数的状态不外乎 4 个,如果有(00)(11)的话可以将(01,10)串在一起,所以这种情况下可以直接输出前(n)个的和。

否则的话,判断能否构成环,如果不可以的话就往后找,找到几个来替换出(00)(11)就可以了。

时间复杂度(O(nlog 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;
}
原文地址:https://www.cnblogs.com/withhope/p/13637396.html