2020 Multi-University Training Contest 7 1007 Game

整个图可以看成一个完全图,最长边必胜,两个端点连的其他边必败,然后剩余边中最长边必胜,最长边连的边必败。。。依次类推
如果1号点连的边中有必胜边,那就必胜,否则必败
 

#include
#include
#include
#include
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);
}
queueq;
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");
    }
}

 

你可能感兴趣的:(1000篇,hdu,思维)