zoukankan      html  css  js  c++  java
  • zoj 2318 Get Out! 计算几何spfa判负环

    题意:给出n个圆心及半径,再给出一个特殊圆心及半径,问这个圆能不能逃出这n个圆的包围

    首先先处理一下,将所有圆平移,使特殊圆在原点上,然后其他圆半径加上特殊圆的半径,这样特殊圆就可看成一个点而已,问题变为该点是否可以逃出实际上对于相交的两个圆,我们可以用他们圆心连线来代替它们。这样问题变为是否存在一个多边形,使得原点在这个多边行内部。

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #include <math.h>
    #include <queue>
    using namespace std;
    #define LL long long
    #define eps 1e-6
    double pi=2*asin(1);
    
    struct circle
    {
        double x,y,r;
    }p[310];
    struct Node
    {
        int v,nxt;
        double w;
    }node[310*310];
    int n,vis[310],f[310],g[310],alloc;
    double d[310];
    void add(int a,int b,double c)
    {
        node[alloc].v=b;
        node[alloc].nxt=g[a];
        node[alloc].w=c;
        g[a]=alloc++;
    }
    double dist(int a,int b)
    {
        return hypot(fabs(p[a].x-p[b].x),fabs(p[a].y-p[b].y));
    }
    bool spfa()
    {
        queue<int>Q;
        for(int i=1;i<=n;i++)
        {
            Q.push(i);
            vis[i]=1;
            f[i]=0;
            d[i]=0;
        }
        while(!Q.empty())
        {
            int u=Q.front();Q.pop();
            vis[u]=0;
            for(int son=g[u];son!=-1;son=node[son].nxt)
            {
                int v=node[son].v;
                double w=node[son].w;
                if(d[v]>eps+d[u]+w)
                {
                    d[v]=d[u]+w;
                    if(!vis[v])
                    {
                        f[v]++;
                        if(f[v]>=n) return false;
                        vis[v]=1;
                        Q.push(v);
                    }
                }
            }
        }
        return true;
    }
    int main()
    {
        int T,i,j;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(i=1;i<=n;i++)
                scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r);
            scanf("%lf%lf%lf",&p[0].x,&p[0].y,&p[0].r);
            for(i=1;i<=n;i++)
            {
                p[i].x-=p[0].x;
                p[i].y-=p[0].y;
                p[i].r+=p[0].r;
            }
            p[0].x=p[0].y=0;
            memset(g,-1,sizeof(g));
            alloc=0;
            for(i=1;i<=n;i++)
            {
                for(j=i+1;j<=n;j++)
                {
                    if(p[i].r+p[j].r-eps<dist(i,j)) continue;
                    double C=acos((p[i].x*p[j].x+p[i].y*p[j].y)/dist(0,i)/dist(0,j));
                    bool flag=(p[i].x*p[j].y-p[j].x*p[i].y)>=0;
                    add(i,j,flag?C:-C);
                    add(j,i,!flag?C:-C);
                }
            }
            if(spfa()) printf("YES
    ");
            else printf("NO
    ");
            if(T) printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    【Linux软件安装】
    Java IO(七)ByteArrayInputStream 和 ByteArrayOutputStream
    Java IO(六) ObjectInputStream 和 ObjectOutputStream
    Java IO(四) InputStream 和 OutputStream
    Java IO(五)字节流 FileInputStream 和 FileOutputStream
    Java IO(三)FileDescriptor
    Java IO(二)File
    Java IO(一)概述
    Java中的集合(十五) Iterator 和 ListIterator、Enumeration
    Java中的自动装箱拆箱
  • 原文地址:https://www.cnblogs.com/zuferj115/p/5221910.html
Copyright © 2011-2022 走看看