总结:
特殊的哈密顿回路通常考虑转化成欧拉回路。
把NP问题转化成可解的东西
把速度看成点,一个很巧妙的转化!
这题利用了欧拉回路存在的充要条件每个联通块的进入和出去的边数相同,等价于所有点出入度相同。
然后要一次性走完,还要联通,因此要最小生成树。
离散化后unique一下就没有孤立点了。所有留下的点都要联通
#include<bits/stdc++.h>
using namespace std;
#define rep(i,l,r) for(register int i = l ; i <= r ; i++)
#define repd(i,r,l) for(register int i = r ; i >= l ; i--)
#define rvc(i,S) for(register int i = 0 ; i < (int)S.size() ; i++)
#define rvcd(i,S) for(register int i = ((int)S.size()) - 1 ; i >= 0 ; i--)
#define fore(i,x) for(register int i = head[x] ; i ; i = e[i].next)
#define pb push_back
#define prev prev_
#define stack stack_
#define mp make_pair
#define fi first
#define se second
typedef long long ll;
typedef pair<int,int> pr;
const int maxn = 4e5 + 10;
const int inf = 1e9;
struct node{
int x,y,w;
bool operator < (node a)const{
return w < a.w;
}
}e[maxn];
int fa[maxn],num[maxn],a[maxn],cnt,m;
ll ans;
int getfa(int x){ return fa[x] == x ? x : fa[x] = getfa(fa[x]); }
inline void merge(int x,int y){
// cout<<x<<" "<<y<<endl;
int p = getfa(x) , q = getfa(y);
if ( p != q ) fa[p] = q;
}
long long plan_roller_coaster(std::vector<int> s, std::vector<int> t){
s.pb(inf) , t.pb(1);
rvc(i,s) a[++cnt] = s[i] , a[++cnt] = t[i];
sort(a + 1,a + cnt + 1);
cnt = unique(a + 1,a + cnt + 1) - a - 1;
rep(i,1,cnt) fa[i] = i;
rvc(i,s){
s[i] = lower_bound(a + 1,a + cnt + 1,s[i]) - a;
t[i] = lower_bound(a + 1,a + cnt + 1,t[i]) - a;
num[s[i]]++;
num[t[i]]--;
merge(s[i],t[i]);
}
rep(i,1,cnt){
num[i] += num[i - 1];
// cout<<num[i]<<" ";
if ( num[i] > 0 ) ans += (ll)num[i] * (a[i + 1] - a[i]) , merge(i,i + 1);
else if ( num[i] < 0 ) merge(i,i + 1);
else if ( i < cnt ) e[++m] = (node){i,i + 1,a[i + 1] - a[i]};
}
// cout<<ans<<endl;
sort(e + 1,e + m + 1);
rep(i,1,m){
int x = e[i].x , y = e[i].y , w = e[i].w;
// cout<<x<<" "<<y<<" "<<w<<endl;
int p = getfa(x) , q = getfa(y);
if ( p != q ) fa[p] = q , ans += w;
}
return ans;
}
int main() {
freopen("input.txt","r",stdin);
int n;
assert(1 == scanf("%d", &n));
int need_answer;
assert(1 == scanf("%d", &need_answer));
std::vector<int> s(n), t(n);
for (int i = 0; i < n; ++i)
assert(2 == scanf("%d%d", &s[i], &t[i]));
long long ans = plan_roller_coaster(s, t);
printf("%lld\n", ans);
return 0;
}