zoukankan      html  css  js  c++  java
  • 【比赛】NOIP2017 奶酪

    开始看到题以为是计算几何,后面发现不是,然后秒掉了。

    可能写SPFA写多了,别人都是并查集做的,我用的是SPFA。

    不过无所谓,我们把题目中的下底面和上表面看成两个点,那么就是求这两个点的连通性,如果连通,出Yes,否则出No。

    转换成图论,如果两个洞的半径乘2大于等于两洞球心之间的距离,那么这两个洞就直接相通,连边,总共平方复杂度建图。

    然后跑SPFA,如果终点的dis不为inf,就可到达。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int MAXN=1000+10,inf=0x3f3f3f3f;
    int T,n,h,p[MAXN],d[MAXN],to[MAXN*MAXN*2],nex[MAXN*MAXN*2],beg[MAXN],w[MAXN*MAXN*2],e,s,t;
    ll r;
    struct node{
        int x,y,z;
    };
    node hole[MAXN];
    inline void read(int &x)
    {
        int data=0,w=1;
        char ch=0;
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')w=-1,ch=getchar();
        while(ch>='0'&&ch<='9')data=(data<<3)+(data<<1)+(ch^'0'),ch=getchar();
        x=data*w;
    }
    inline bool connect(int i,int j)
    {
        if(4ll*r*r-(ll)(hole[i].x-hole[j].x)*(ll)(hole[i].x-hole[j].x)>=(ll)(hole[i].y-hole[j].y)*(ll)(hole[i].y-hole[j].y)+(ll)(hole[i].z-hole[j].z)*(ll)(hole[i].z-hole[j].z))return true;
        else return false;
    }
    inline void insert(int x,int y,int z)
    {
        to[++e]=y;
        nex[e]=beg[x];
        beg[x]=e;
        w[e]=z;
    }
    inline void Build()
    {
        for(register int i=1;i<=n;++i)
            for(register int j=i+1;j<=n;++j)
                if(connect(i,j))insert(i,j,1),insert(j,i,1);
        for(register int i=1;i<=n;++i)
            if(hole[i].z-r<=0)insert(s,i,1);
        for(register int i=1;i<=n;++i)
            if(hole[i].z+r>=h)insert(i,t,1);
    }
    inline void SPFA()
    {
        for(register int i=1;i<=t;++i)d[i]=inf;
        queue<int> q;
        q.push(s);
        p[s]=1;
        d[s]=0;
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            p[x]=0;
            for(register int i=beg[x];i;i=nex[i])
                if(d[to[i]]>d[x]+w[i])
                {
                    d[to[i]]=d[x]+w[i];
                    if(!p[to[i]])
                    {
                        p[to[i]]=1;
                        q.push(to[i]);
                    }
                }
        }
    }
    inline void init()
    {
        e=0;
        memset(beg,0,sizeof(beg));
        memset(p,0,sizeof(p));
    }
    int main()
    {
        freopen("cheese.in","r",stdin);
        freopen("cheese.out","w",stdout);
        read(T);
        while(T--)
        {
            init();
            read(n);read(h);scanf("%lld",&r);
            s=n+1,t=n+2;
            for(register int i=1;i<=n;++i)read(hole[i].x),read(hole[i].y),read(hole[i].z);
            Build();
            SPFA();
            if(d[t]<inf)printf("Yes
    ");
            else printf("No
    ");
        }
        return 0;
    }
    NOIP2017 奶酪
  • 相关阅读:
    数组对象去重
    数组对象中key值为数组的数据处理成多个对应的数组对象
    数组对象相同的key值合并,并且把对应的id放到一个数组
    vue使用element-ui tabs切换 实现按需加载
    vue使用element-ui tabs切换echarts 解决宽度100% 问题
    递归获取所有JSON对象
    JS通过内核判断各种浏览器区分360与谷歌
    vue 跳转当前页面不刷新问题
    docker 常用命令
    java 比较时间的几种方法
  • 原文地址:https://www.cnblogs.com/hongyj/p/8000907.html
Copyright © 2011-2022 走看看