Turtle and Intersected Segments
#include<bits/stdc++.h>
#define ll long long
#define Blue_Archive return 0
using namespace std;
const int N = 5e5 + 3;
const int INF = 0x0d000721;
int T;
int n;
int cnt;
int fa[N];
struct miku
{
int l;
int r;
int w;
}a[N],e[N << 1];
vector<int> vec,add[N << 1],del[N < 1];
inline int find(int x){return x == fa[x] ? x : fa[x] = find(fa[x]);}
signed main()
{
freopen("data.in","r",stdin);freopen("data.out","w",stdout);
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin >> T;
while(T --)
{
cin >> n;
cnt = 0;vec.clear();
for(int i = 1;i <= n;i ++)
{
fa[i] = i;
cin >> a[i].l >> a[i].r >> a[i].w;
vec.push_back(a[i].l);
vec.push_back(a[i].r);
}
sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(),vec.end()),vec.end());//离散化
for(int i = 1;i <= (int)vec.size();i ++) add[i].clear(),del[i].clear();//多测清空
for(int i = 1;i <= n;i ++)
{
add[lower_bound(vec.begin(),vec.end(),a[i].l) - vec.begin() + 1].push_back(i);//分别存储离散化后的区间左端点和右端点
del[lower_bound(vec.begin(),vec.end(),a[i].r) - vec.begin() + 1].push_back(i);
}
set<pair<int,int> > s;
for(int i = 1;i <= (int)vec.size();i ++)
{
for(int x : add[i])//从这里开始的区间
{
pair<int,int> tmp = {a[x].w,x};
auto it = s.lower_bound(tmp);
if(it != s.end()) e[++ cnt] = {it -> second,x,(it -> first) - a[x].w};//加上后继
if(it != s.begin()) it --,e[++ cnt] = {it -> second,x,a[x].w - (it -> first)};//加上前驱
s.insert(tmp);//插入维护的区间
}
for(int x : del[i])//在这里结束的区间
{
pair<int,int> tmp = {a[x].w,x};
s.erase(tmp);//在维护的区间内删除
}
}
int tim = 0;//最小生成树板子
ll ans = 0;
sort(e + 1,e + cnt + 1,[](miku a,miku b){return a.w < b.w;});
for(int i = 1;i <= cnt;i ++)
{
if(find(e[i].l) != find(e[i].r))
{
fa[find(e[i].l)] = find(e[i].r);
++ tim;
ans += e[i].w;
}
}
cout << (tim == n - 1 ? ans : -1) << '\n';
}
Blue_Archive;
}
与你的日常,便是奇迹

浙公网安备 33010602011771号