Problem:
Score : 700 points

Problem Statement

We have a directed weighted graph with N vertices.
Each vertex has two integers written on it, and the integers written on Vertex i are A_i and B_i.

In this graph, there is an edge from Vertex x to Vertex y for all pairs 1 \leq x,y \leq N, and its weight is {\rm min}(A_x,B_y).

We will consider a directed cycle in this graph that visits every vertex exactly once.
Find the minimum total weight of the edges in such a cycle.

Constraints

2 \leq N \leq 10^5

1 \leq A_i \leq 10^9

1 \leq B_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 B_1
A_2 B_2
:
A_N B_N

Output

Print the minimum total weight of the edges in such a cycle.

Sample Input 1

3
1 5
4 2
6 3

Sample Output 1

7

Consider the cycle 1→3→2→1. The weights of those edges are {\rm min}(A_1,B_3)=1, {\rm min}(A_3,B_2)=2 and {\rm min}(A_2,B_1)=4, for a total of 7.
As there is no cycle with a total weight of less than 7, the answer is 7.

Sample Input 2

4
1 5
2 6
3 7
4 8

Sample Output 2

10

Sample Input 3

6
19 92
64 64
78 48
57 33
73 6
95 73

Sample Output 3

227

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <numeric>
#include <cstring>
#include <unordered_set>
#include <unordered_map>

using namespace std;
 
typedef long long ll;
typedef pair<ll, ll> P;
static const ll INF = 1000010000;
static const ll MOD = 1000000007;
 
#define FOR(i, a, b) for(ll i = (a); i < (b); ++i)
#define REP(i, n) for(ll i = 0; i < (n); ++i)
#define SORT(v) sort(v.begin(), v.end());
#define pb push_back
#define mp make_pair
#define np next_permutation

//int dx[4] = {0,1,0,-1}, dy[4] = {-1,0,1,0};
//int dx5[5] = {-1,0,0,0,1}, dy5[5] = {0,-1,0,1,0};
//int dx8[8] = {-1,0,1,1,1,0,-1,-1}, dy8[8] = {1,1,1,0,-1,-1,-1,0};
//int dx9[9] = {-1,0,1,1,1,0,-1,-1,0}, dy9[9] = {1,1,1,0,-1,-1,-1,0,0};

struct UnionFind
{
  vector< int > data;

  UnionFind(int sz)
  {
    data.assign(sz, -1);
  }

  bool unite(int x, int y)
  {
    x = find(x), y = find(y);
    if(x == y) return(false);
    if(data[x] > data[y]) swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return(true);
  }

  int find(int k)
  {
    if(data[k] < 0) return(k);
    return(data[k] = find(data[k]));
  }

  int size(int k)
  {
    return(-data[find(k)]);
  }
};


int main(){
    ll n;
    cin >> n;
    priority_queue<P> pq;
    vector<ll> a(n), b(n);
    vector<P> sa(n), sb(n);
    vector<ll> ua(n, -1), ub(n, -1);
    UnionFind uf(n);
    REP(i, n){
        ll ta, tb;
        cin >> ta >> tb;
        pq.push(P(ta, i));
        pq.push(P(tb, i+n));
        a[i] = ta;
        b[i] = tb;
        sa[i] = P(ta, i);
        sb[i] = P(tb, i);
    }
    SORT(sa);
    SORT(sb);
    int acnt = 0;
    int bcnt = 0;
    ll ans = 0;
    REP(i, n - 2){
        P tmp = pq.top(); pq.pop();
        if(tmp.second < n){
            int nb;
            FOR(j, bcnt, n){
                if(ub[tmp.second] == sb[j].second || tmp.second == sb[j].second || ub[sb[j].second] != -1){

                }else{
                    nb = j;
                    break;
                }
            }
            ans += sb[nb].first;
            ua[tmp.second] = sb[nb].second;
            ub[sb[nb].second] = tmp.second;
            uf.unite(tmp.second, sb[nb].second);
            if(nb == bcnt) bcnt++;
        }else{
            tmp.second -= n;
            int na;
            FOR(j, acnt, n){
                if(ua[tmp.second] == sa[j].second || tmp.second == sa[j].second || ua[sa[j].second] != -1){

                }else{
                    na = j;
                    break;
                }
            }
            ans += sa[na].first;
            ub[tmp.second] = sa[na].second;
            ua[sa[na].second] = tmp.second;
            uf.unite(tmp.second, sa[na].second);
            if(na == acnt) acnt++;
        }
    }
    ll a1, a2, b1, b2;
    a1 = -1;
    REP(i, n){
        if(ua[i] == -1 && ub[i] == -1){
            a1 = a[i];
            b2 = b[i];
        }else if(ua[i] == -1){
            a2 = a[i];
        }else if(ub[i] == -1){
            b1 = b[i];
        }
    }
    if(a1 == -1){
        a1 = a2 = b1 = b2 = -1;
        REP(i, n){
            if(ua[i] == -1){
                if(a1 == -1){
                    a1 = i;
                }else{
                    a2 = i;
                }
            }
            if(ub[i] == -1){
                if(b1 == -1){
                    b1 = i;
                }else{
                    b2 = i;
                }
            }
        }
        if(uf.find(a1) == uf.find(b1)){
            ans += min(a[a1], b[b1]) + min(a[a2], b[b2]);            
        }else{
            ans += min(a[a1], b[b2]) + min(a[a2], b[b1]);       
        }
    }else{
        ans += min(a1, b1) + min(a2, b2);
    }
    cout << ans << endl;
}