acmicpc.sdnu.edu.cn 1012区间合并

Description:

给定n个开区间,合并他们中的重合者,输出合并后的区间数量。

Input:

第一行:n(1 <= n <= 1000)
第2至第n+1行:每行两个整数,第i行的两个整数表示第i-1个区间的左边界和右边界。

Output:

合并后所剩余的区间数量。

一道经典的并查集问题。

并查集问题讨论关于不相交集合的问题,对于任意两个集合A,B,若有元素x∈A则x∉B,即可以通过集合中任一元素代表该集合。新问题是如何选择代表该集合的元素?代表元素最好能惰性变化。

于是在集合中添加数据结构(即数据间相互关系),由于树有且仅有且必须有一个根节点,于是选择树形结构作为集合内数据逻辑关系模型。

而问题将分为两个子问题:①两线段是否重合,②集合合并问题

①两线段是否重合,纯几何问题,仅提供True或False以标记是否合并

②集合合并,当发现集合A与集合B出现重叠,将二者重合。

#include <stdio.h>

struct NODE{
	int left,right;
	int father;
}node[1010];

bool Judge(int a, int b){
	if(node[b].left >= node[a].right || node[b].right <= node[a].left){
		return false;
	}
	else return true;
}

void Union(int a, int b){
	int af = a;
	int bf = b;
	while(node[af].father != af) af = node[af].father;
	while(node[bf].father != bf) bf = node[bf].father;
	if(af < bf){
		node[bf].father = af;
	}
	else if(bf < af){
		node[af].father = bf;
	}
}

int main(){
	int n;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d%d",&node[i].left, &node[i].right);
		node[i].father = i;
	}
	for(int i=0;i<n-1;i++){
		for(int k=i+1;k<n;k++){
			if(Judge(i,k)){
				Union(i,k);
			}
		}
	}
	int sum = 0;
	for(int i=0;i<n;i++){
		if(node[i].father == i) sum++;
	}
	printf("%d\n",sum);
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值