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

来源:互联网 发布:店铺宝贝优化 编辑:程序博客网 时间:2024/05/17 14:17

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
原创粉丝点击