D. Segment Tree ------ thinking (hard) + Sort + set / good

As the name of the task implies, you are asked to do some work with segments and trees.

Recall that a tree is a connected undirected graph such that there is exactly one simple path between every pair of its vertices.

You are given n segments [l1,r1],[l2,r2],…,[ln,rn], li<ri for every i. It is guaranteed that all segments’ endpoints are integers, and all endpoints are unique — there is no pair of segments such that they start in the same point, end in the same point or one starts in the same point the other one ends.

Let’s generate a graph with n vertices from these segments. Vertices v and u are connected by an edge if and only if segments [lv,rv] and [lu,ru] intersect and neither of it lies fully inside the other one.

For example, pairs ([1,3],[2,4]) and ([5,10],[3,7]) will induce the edges but pairs ([1,2],[3,4]) and ([5,7],[3,10]) will not.

Determine if the resulting graph is a tree or not.

Input
The first line contains a single integer n (1≤n≤5⋅105) — the number of segments.

The i-th of the next n lines contain the description of the i-th segment — two integers li and ri (1≤li<ri≤2n).

It is guaranteed that all segments borders are pairwise distinct.

Output
Print “YES” if the resulting graph is a tree and “NO” otherwise.

Examples
inputCopy

6
9 12
2 11
1 3
6 10
5 7
4 8
outputCopy
YES
inputCopy
5
1 3
2 4
5 9
6 8
7 10
outputCopy
NO
inputCopy
5
5 8
3 6
2 9
7 10
1 4
outputCopy
NO
Note
The graph corresponding to the first example:

Here Insert Picture Description

The graph corresponding to the second example:

Here Insert Picture Description

The graph corresponding to the third example:

Here Insert Picture Description

Meaning of the questions: give you n line segments [li, ri], the endpoint of each segment is not the same. If there are two line segments intersect and does not contain, we will build on their side. For example [l1, r1], [l2, r2] intersects the line segment edge 1 and 2 construction. Entitled to ask whether you can build a tree, and there is no ring.

Analysis: Violence O (n ^ 2) is not desirable. Require O (nlogn) algorithm.
Endpoint descending order for all sections of the left. We store a vector with the current tuple left point i, the right end point -i, then give sorting vector. Suppose the current is i, then the endpoint before i must intersect, a tree up to n-1 edges, and we need to use disjoint-set to maintain the
information stored with the left point set, each encounter -i the case, then the front of the line must intersect, and then we build the side, with disjoint-set maintenance connected component. Then delete the line

Said there may not be a good
side with a video explaining better
https://www.bilibili.com/video/av80058531?p=4



#include<bits/stdc++.h>
using namespace std;
const int N=1e6+100;
pair<int,int> a[N];
int fa[N];
int n;
vector<pair<int,int> > p;
int find(int x)
{
	if(x!=fa[x]) return fa[x]=find(fa[x]);
	return fa[x];
}
void slove()
{
	cin>>n;
	for(int i=1;i<=n;i++) 
	{
		fa[i]=i;
		cin>>a[i].first>>a[i].second;
		p.push_back(make_pair(a[i].first,i));
		p.push_back(make_pair(a[i].second,-i));
	}
	sort(p.begin(),p.end()); //这边排序后,遇到-i的情况,那么之前的线段一定与之相交
	int cnt=0;
	set<pair<int,int> > s;
	for(int i=0;i<p.size();i++)
	{
		if(p[i].second>0)
		{
			s.insert(make_pair(-p[i].first,p[i].second)); //加个负号,这边从大到小排序
		}
		else
		{
			for(auto x:s)
			{
				int id=-p[i].second;
				if(a[id].first==-x.first) break;//如果遇到了自己就break
				if(cnt==n-1) //如果之前已经建了n-1条边,这边一定输出NO
				{
					puts("NO");
					return ;
				}
				if(find(id)==find(x.second)) //这边会构成回路
				{
					puts("NO");
					return ;
				}
				fa[find(id)]=fa[find(x.second)];  
				cnt++; 
			}
			s.erase(make_pair(-a[-p[i].second].first,-p[i].second));//删除该线段
		}

	}   
	if(cnt==n-1) puts("YES");
	else puts("NO"); 
}
int main()
{
	slove();
}

Published 309 original articles · won praise 6 · views 5254

Guess you like

Origin blog.csdn.net/qq_43690454/article/details/104081553