Clique Problem

link

巧妙的贪心。最近发现自己很多板块都能力不足,比如思维和贪心等知识点,这都是以前周老师不是很重视的地方(还有就是最近很容易怀旧,刚毕业的人都这样)。

想到先去绝对值。由于联通是双向的过程,所以统计一次即可,想到按x升序排序,这样点i和j(i在j后面)有连边就需要满足 \(x_i-x_j\ge w_i+w_j\) ,移项得到 \(w_i-w_i\ge w_j+x_j\) 。而很明显前者和后者都是只和i或者j有关的量,所以可以看成是轴上的许多点;而题目保证了w的非负,所以每一个点的x-w和x+w可以看成是一条线段,两个点有连边当且仅当线段右端点不大于另一条线段的左端点,即两条线段无重合部分时,问题变成了经典的贪心问题。

然后尴尬的发现写挂了,交了七八次。原因是写法有大锅,假如指针越出当前范围时是不能被统计入答案的。

code:

#include<bits/stdc++.h>
//#define zczc
#define int long long
const int N=200010;
using namespace std;
inline void read(int &wh){
    wh=0;int f=1;char w=getchar();
    while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
    while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
    wh*=f;return;
}

struct node{
	int a,b;
}a[N];
int m;

inline bool cmp(node s1,node s2){
	if(s1.b==s2.b)return s1.a<s2.a;
	else return s1.b<s2.b;
}

signed main(){
	
	#ifdef zczc
	freopen("in.txt","r",stdin);
	#endif
	
	read(m);int s1,s2,ans=0,last=-1e12;
	for(int i=1;i<=m;i++){
		read(s1);read(s2);
		a[i].a=s1-s2,a[i].b=s1+s2;
	}
	sort(a+1,a+m+1,cmp);
	for(int now=1;now<=m;now++){
		while(now<=m&&a[now].a<last)now++;
		if(now<=m)ans++;last=a[now].b;
	}
	printf("%lld",ans);
	
	return 0;
}
posted @ 2022-06-24 09:03  Feyn618  阅读(31)  评论(0编辑  收藏  举报