A
B

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;
}
posted @ 2025-08-24 06:45  MyShiroko  阅读(21)  评论(0)    收藏  举报