D. Clique Problem(消绝对值+区间线段贪心)

https://codeforces.com/problemset/problem/527/D


题目描述

数轴上有 nn 个点,第 ii 个点的坐标为 x_ixi​,权值为 w_iwi​。两个点 i,ji,j 之间存在一条边当且仅当 abs(x_i-x_j)\geq w_i+w_jabs(xi​−xj​)≥wi​+wj​ 。 你需要求出这张图的最大团的点数。

团的定义:两两之间有边的顶点集合。

输入格式

第一行一个整数 nn,接下来 nn 行每行两个整数 x_i,w_ixi​,wi​ 。

输出格式

一行一个整数表示答案。

感谢@Asougi_Kazuma 提供的翻译。

感谢@皎月半洒花 将翻译改成了正常人能看明白的翻译。

输入输出样例

输入 #1复制

4
2 3
3 1
6 1
0 2

输出 #1复制

3

说明/提示

If you happen to know how to solve this problem without using the specific properties of the graph formulated in the problem statement, then you are able to get a prize of one million dollars!

The picture for the sample test.


题目注意:这个团中两两都是有连边的才能是一个团。

思路:首先对绝对值进行拆分。

如果一个点对(i,j)满足|xi - xj| ≥ wi + wj 则在i,j之间连边

那么有

xi-xj>=wi+wj   xi-wi>=xj+wj

xj-xi>=wi+wj  xj-wj>=xi+wj(这个式子与上式等效)所以分析上面一个一样。

令Xi=xi-wi,Yj=xj+wj--->也就是说如果Xi>=Yj,就可以连边。现在把这个Xi的值看成一个端点值,Yj的值看成一个端点值。

那么样例模拟下来大致是

|________|(Yj)

          (Xi)|__________|

                                   |________|

之类的。

问题就转化成求怎么选使得最多有多少个区间没有交界。那么这就是个区间贪心的经典问题。

对区间坐标按Y去从小到大排序,如果有Xi>Y,那么ans++,同时更新Y的最大值。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+100;
typedef long long LL;
struct node{
	LL x,y;
}nodes[maxn];
bool cmp(node A,node B){
	if(A.y==B.y) return A.x<B.x;
	return A.y<B.y;
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n;cin>>n;
  for(LL i=1;i<=n;i++){
  	LL a,b;cin>>a>>b;
  	nodes[i].x=a-b;nodes[i].y=a+b; 
  }
  sort(nodes+1,nodes+1+n,cmp);
  LL Y=nodes[1].y;LL ans=1;
  for(LL i=1;i<=n;i++){
  	if(nodes[i].x>=Y){
  		ans++;
  		Y=nodes[i].y;
	}
  }
  cout<<ans<<endl;
return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/108553545