题目大意是给你5e5条线段,规定相交的线段可以让他们彼此的编号之间连出一条边。注意线段互相包含不算相交,且没有重复的端点,端点都是从1~2n,问你最后练出的图是不是一棵树
根据树的定义我们知道树的边数一定是n-1的,那么我们可以记录一下边数如果不是n-1那么就是NO否则我们再遍历一下图看看是不是可以组成一颗树
这里CF官方题解给了一种叫做sweep line approach的方法可以nlogn判断具体哪两个线段相交
首先,我们把线段的左端点右端点拆分,变成{v,id}v代表值id代表这是输入顺序的第几个例如1 3线段就要拆分成1 1 和 3 1
然后,我们把拆分的线段加入一个vector中再按照第一个值排序从小到大
接着,我们开一个set来记录vector内的元素
算法开始,我们最外层枚举vector内的元素,首先判断当前set内是否有这个元素如果有就删除继续走。因为如果有的话这都是右端点了直接删除可以避免重复计数
否则的话我们就遍历set看看里面有多少值是小于当前的节点编号的右端点值的小于就说明这俩一定相交那么我们就记录上就行了
最后把这个右端点再放入set中即可
1 | for(int i=0;i<v.size();i++) //sweep line approach |
然后我们dfs一遍看看是不是树就行了
1 |
|