Segment Tree(set+并查集)

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 nn segments [l1,r1],[l2,r2],…,[ln,rn][l1,r1],[l2,r2],…,[ln,rn], li<rili<ri for every ii. 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 nn vertices from these segments. Vertices vv and uu are connected by an edge if and only if segments [lv,rv][lv,rv] and [lu,ru][lu,ru] intersect and neither of it lies fully inside the other one.

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

Determine if the resulting graph is a tree or not.

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

The ii-th of the next nn lines contain the description of the ii-th segment — two integers lili and riri (1≤li<ri≤2n1≤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
Input
6
9 12
2 11
1 3
6 10
5 7
4 8
Output
YES
Input
5
1 3
2 4
5 9
6 8
7 10
Output
NO
Input
5
5 8
3 6
2 9
7 10
1 4
Output
NO
Note
The graph corresponding to the first example:
在这里插入图片描述

扫描二维码关注公众号,回复: 9082216 查看本文章

The graph corresponding to the second example:
在这里插入图片描述

The graph corresponding to the third example:
在这里插入图片描述
思路:
脑子抽了一开始用的主席树,过了72个样例之后被卡住了。主要是有一种情况是不能判断出来的,那就是有环的,而且总共的边数=n-1这样的情况。
先按照左端点排序,对于后面的区间,左端点一定大于上面的,我们只需要找到当前的左端点<之前的右端点的点,然后判断右端点是否大于当前右端点就好了。这个操作利用set来实现。除此之外,我们还应该利用并查集判断环。
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxx=5e5+100;
struct node{
	int l,r;
	bool operator<(const node &a)const{
		return l<a.l;
	}
}p[maxx];
int f[maxx];
map<int,int> mp;
set<int> s;
int n;

inline int getf(int u)
{
	if(u==f[u]) return f[u];
	else return f[u]=getf(f[u]);
}
inline int merge(int u,int v)
{
	int t1=getf(u);
	int t2=getf(v);
	if(t1==t2) return 1;
	f[t1]=t2;
	return 0;
}
int main()
{
	scanf("%d",&n);
	mp.clear();
	s.clear();
	for(int i=1;i<=n;i++) scanf("%d%d",&p[i].l,&p[i].r),f[i]=i;
	sort(p+1,p+1+n);
	int cnt=0;
	for(int i=1;i<=n;i++) mp[p[i].r]=++cnt;
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		set<int> ::iterator it=s.lower_bound(p[i].l);
		while(it!=s.end()&&*it<p[i].r)
		{
			if(merge(mp[*it],i))
			{
				cout<<"NO"<<endl;
				return 0;
			}
			it++; 
			ans++;
		}
		s.insert(p[i].r);
	}
	if(ans!=n-1) cout<<"NO"<<endl;
	else cout<<"YES"<<endl;
	return 0;
}

努力加油a啊,(o)/~

发布了414 篇原创文章 · 获赞 23 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/starlet_kiss/article/details/104180480
今日推荐