1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| #include <algorithm> #include <iostream> #include <cstdio> #include <cctype>
using namespace std;
typedef long long LL;
inline int read() { int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) f=ch=='-'?-1:f,ch=getchar(); while (isdigit(ch)) x=x*10+ch-'0',ch=getchar(); return x*f; }
const int N=30005; const int K=400; const int M=(K<<1)+5; const int L=M*M;
typedef pair<int,int> P; typedef pair<P,P> PI; #define mkp(a,b) make_pair(a,b) #define ft first #define sd second
int x[N],y[N],a[N],fa[N],rk[N],reach[N]; PI list[L]; LL srt[N]; int T,n,m,cnt,ans,ti;
int gcd(int x,int y){return y?gcd(y,x%y):x;}
int getfather(int son) { if (reach[son]!=ti) return reach[son]=ti,rk[son]=0,fa[son]=son; else return fa[son]==son?son:fa[son]=getfather(fa[son]); }
inline bool merge(int x,int y) { x=getfather(x),y=getfather(y); if (x==y) return 0; if (rk[x]<rk[y]) swap(x,y); return fa[y]=x,rk[x]+=rk[x]==rk[y],1; }
int main() { freopen("par.in","r",stdin),freopen("par.out","w",stdout); for (T=read();T--;) { n=read(); for (int i=1;i<=n;++i) x[i]=read(),y[i]=read(); m=min(K*2,n),cnt=0; for (int i=1;i<=m;++i) for (int j=1;j<i;++j) { int x_=x[i]-x[j],y_=y[i]-y[j]; if (x_<0||!x_&&y_<0) x_*=-1,y_*=-1; int g=gcd(abs(x_),abs(y_)); list[++cnt]=mkp(mkp(y_/g,x_/g),mkp(j,i)); } sort(list+1,list+1+cnt),ans=n; for (int st=1,en;st<=cnt;st=en) { for (en=st;en<=cnt&&list[st].ft==list[en].ft;++en); if (n<=K*2) { int cur=n;++ti; for (int i=st;i<en;++i) cur-=merge(list[i].sd.ft,list[i].sd.sd); ans=min(ans,cur); } else if (en-st>=K) { int p=list[st].ft.ft,q=list[st].ft.sd; for (int i=1;i<=n;++i) srt[i]=1ll*p*x[i]-1ll*q*y[i]; sort(srt+1,srt+1+n),ans=min(ans,(int)(unique(srt+1,srt+1+n)-(srt+1))); } } printf("%d\n",ans); } fclose(stdin),fclose(stdout); return 0; }
|