考虑将所有的
A
A
A和
B
B
B从小到大排序。
若前
n
n
n小中全部都是
A
A
A或全部都是
B
B
B容易构造达到下界。否则若同时存在某个
A
i
A_i
Ai或
B
i
B_i
Bi也可以构造达到下界(同时存在
A
i
A_i
Ai和
B
i
B_i
Bi的
i
i
i的个数等于同时不存在
A
i
A_i
Ai和
B
i
B_i
Bi的
i
i
i的个数,那么我们可以在环上交替放两种数,最后将剩余的只存在
A
i
A_i
Ai或只存在
B
i
B_i
Bi的数插在它们之间)。
如果既有
A
A
A也有
B
B
B,且每个
i
i
i恰好出现一次的话,我们枚举一个后面的替换即可,注意有可能换成全部是
A
A
A或全部是
B
B
B的。
时间复杂度
O
(
N
log
N
)
\mathcal O(N\log N)
O(NlogN)。
#include <bits/stdc++.h>
#define FR first
#define SE second
using namespace std;
typedef long long ll;
typedef pair<int,int> pr;
pr a[200005],num[100005];
bool vis[100005];
int main() {
int n;
scanf("%d",&n);
ll s1=0,s2=0;
for(int i=1;i<=n;i++) {
int x,y;
scanf("%d%d",&x,&y);
a[2*i-1]=pr(x,i);
a[2*i]=pr(y,i);
s1+=x;s2+=y;
num[i]=pr(x,y);
}
sort(a+1,a+2*n+1);
ll s=0;
bool ok=0;
for(int i=1;i<=n;i++) {
s+=a[i].FR;
if (!vis[a[i].SE]) vis[a[i].SE]=1;
else ok=1;
}
if (ok) {
printf("%lld\n",s);
return 0;
}
ll ans=min(s1,s2);
for(int i=1;i<=n;i++) {
int x=a[i].SE;
ans=min(ans,s-a[i].FR+num[x].FR+num[x].SE-((i==n)?a[n-1].FR:a[n].FR));
}
printf("%lld\n",ans);
return 0;
}