整个图可以看成一个完全图,最长边必胜,两个端点连的其他边必败,然后剩余边中最长边必胜,最长边连的边必败。。。依次类推
如果1号点连的边中有必胜边,那就必胜,否则必败
#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
#define ll long long
#define maxn 3050
ll mp[maxn][maxn],dis[maxn][maxn];ll n;
struct node
{
ll x,y;
}a[maxn];
struct Edge
{
ll x,y,w;
}e[maxn*maxn];
ll js(node a,node b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
queue<ll>q;
bool cmp(Edge a,Edge b)
{
return a.w>b.w;
}
void slove(ll cnt)
{
//memset(vis,0,sizeof(vis));
//printf("mx=%d\n",mx);
sort(e+1,e+1+cnt,cmp);
for(ll i=1;i<=cnt;i++)
{
ll x=e[i].x,y=e[i].y;
if(mp[x][y]==0)
{
//printf("i=%lld x=%lld y=%lld\n",i,x,y);
mp[x][y]=mp[y][x]=1;
for(ll v=1;v<=n;v++)
{
if(mp[x][v]==0) mp[x][v]=mp[v][x]=-1;
}
for(ll v=1;v<=n;v++)
{
if(mp[y][v]==0) mp[y][v]=mp[v][y]=-1;
}
}
}
}
int main()
{
ll t;
scanf("%lld",&t);
while(t--)
{
//while(!q.empty()) q.pop();
scanf("%lld",&n);
for(ll i=0;i<=n+10;i++)
{
for(ll j=0;j<=n+10;j++) mp[i][j]=0,dis[i][j]=0;
}
for(ll i=1;i<=n;i++)
{
scanf("%lld %lld",&a[i].x,&a[i].y);
}
ll mx=0,cnt=0;
for(ll i=1;i<=n;i++)
{
for(ll j=i+1;j<=n;j++)
{
dis[j][i]=dis[i][j]=js(a[i],a[j]);
mx=max(dis[i][j],mx);
++cnt;
e[cnt].x=i;e[cnt].y=j;e[cnt].w=dis[i][j];
}
}
slove(cnt);
ll f=0;
for(ll i=2;i<=n;i++)
{
if(mp[1][i]==1)
{
f=1;
break;
}
}
if(f==1) printf("YES\n");
else printf("NO\n");
}
}