题目梗概
坐标轴上有n个点,每个点有一个权值。
如果两个点满足 |xi−xj|>=wi+wj ,那么就在这两个点上建边。
求图中最大团的大小。
解题思路
转换条件,如果两个点满足 xj−wj>=xi+wi||xi−wi>=xj+wj 那么就有边。
因为 wi>0 ,所以必然有 xi+wi>xi−wi ,那么条件可以看成两个关于 i <script type="math/tex" id="MathJax-Element-9">i</script>的区间不相交。
贪心求不相交的最多线段就可以。
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=200005;
inline int _read(){
int num=0;char ch=getchar();
while(ch<'0'||ch>'9') ch=getchar();
while(ch>='0'&&ch<='9') num=num*10+ch-48,ch=getchar();
return num;
}
struct jz{
int x,y;
bool operator<(const jz &b)const{return x<b.x;}
}a[maxn];
int n;
int main(){
freopen("exam.in","r",stdin);
freopen("exam.out","w",stdout);
n=_read();
for (int i=1;i<=n;i++){
int x=_read(),w=_read();
a[i].x=x-w;a[i].y=x+w;
}
sort(a+1,a+1+n);
//for (int i=1;i<=n;i++) printf("%d %d\n",a[i].x,a[i].y);
int tail=-2147483647,ans=0;
for (int i=1;i<=n;i++)
if (a[i].x>=tail) tail=a[i].y,ans++;else
if (a[i].y<tail) tail=a[i].y;
printf("%d\n",ans);
return 0;
}