BNUOJ33566 Cycling Roads(并查集+判断两线段相交)

Cycling Roads

1000ms
65536KB
This problem will be judged on Ural. Original ID:  1966
64-bit integer IO format:  %lld      Java class name:  (Any)
Font Size:   
Type: 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •                    
  • When Vova was in Shenzhen, he rented a bike and spent most of the time cycling around the city. Vova was approaching one of the city parks when he noticed the park plan hanging opposite the central entrance. The plan had several marble statues marked on it. One of such statues stood right there, by the park entrance. Vova wanted to ride in the park on the bike and take photos of all statues. The park territory has multiple bidirectional cycling roads. Each cycling road starts and ends at a marble statue and can be represented as a segment on the plane. If two cycling roads share a common point, then Vova can turn on this point from one road to the other. If the statue stands right on the road, it doesn't interfere with the traffic in any way and can be photoed from the road.
    Can Vova get to all statues in the park riding his bike along cycling roads only?

    Input

    The first line contains integers  n and  m that are the number of statues and cycling roads in the park  (1 ≤  m <  n ≤ 200) . Then  n lines follow, each of them contains the coordinates of one statue on the park plan. The coordinates are integers, their absolute values don't exceed 30 000. Any two statues have distinct coordinates. Each of the following  m lines contains two distinct integers from 1 to  n that are the numbers of the statues that have a cycling road between them.

    Output

    Print “YES” if Vova can get from the park entrance to all the park statues, moving along cycling roads only, and “NO” otherwise.

    Sample Input

    input output
    4 2
    0 0
    1 0
    1 1
    0 1
    1 3
    4 2
    
    YES
    
    4 3
    0 0
    1 0
    1 1
    0 1
    1 2
    2 1
    3 4
    
    NO
    
    3 2
    0 0
    1 0
    1 1
    1 3
    3 2
    
    YES
    

    Source

    题目大意:在平面内给出n个点的坐标和m条道路,如果两条道路有交点,那么它们任意两点是相通。最后问你判断所有的点是不是在一个任意两点是相通的,也就是问是不是一个边通块。
    #include <stdio.h>
    #include <iostream>
    #include <math.h>
    #include <algorithm>
    using namespace std;
    struct EDG
    {
        int u,v;
    };
    struct point
    {
        double x,y;
    };
    point p[305];
    
    double fan(double x,double y)
    {
        return x>y?x:y;
    }
    
    double fin(double c,double d)
    {
        return c<d?c:d;
    }
    
    double cnt(point a,point b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    
    int is(point a,point b,point c,point d)//判断两条线段是不是连通
    {
        if(a.x==b.x&&c.x==d.x)
        {
            return 0;
        }
        if(a.x==b.x&&c.x!=d.x)
        {
            double m1=a.x;
            double m2=(a.x-c.x)*(d.y-c.y)/(d.x-c.x)+c.y;
            if(m1<=fan(a.x,b.x)&&m1>=fin(a.x,b.x)&&m2>=fin(a.y,b.y)&&m2<=fan(a.y,b.y)&&m1<=fan(c.x,d.x)&&m1>=fin(c.x,d.x)&&m2>=fin(c.y,d.y)&&m2<=fan(c.y,d.y))
                return 1;
        }
        if(c.x==d.x&&a.x!=b.x)
        {
            double m1=c.x;
            double m2=a.y+(b.y-a.y)*(c.x-a.x)/(b.x-a.x);
            if(m1<=fan(a.x,b.x)&&m1>=fin(a.x,b.x)&&m2>=fin(a.y,b.y)&&m2<=fan(a.y,b.y)&&m1<=fan(c.x,d.x)&&m1>=fin(c.x,d.x)&&m2>=fin(c.y,d.y)&&m2<=fan(c.y,d.y))
                return 1;
        }
        double k1=(b.y-a.y)/(b.x-a.x);
        double k2=(d.y-c.y)/(d.x-c.x);
        double m1,m2,x,y;
        if(k1==k2)  return 0;
        else
        {
            m1=a.y-k1*a.x;
            m2=c.y-k2*c.x;
            x=(m1-m2)/(k2-k1);
            y=k1*x+m1;
            if(x<=fan(a.x,b.x)&&x>=fin(a.x,b.x)&&y>=fin(a.y,b.y)&&y<=fan(a.y,b.y)&&x<=fan(c.x,d.x)&&x>=fin(c.x,d.x)&&y>=fin(c.y,d.y)&&y<=fan(c.y,d.y))
                return 1;
        }
        return 0;
    }
    int father[305];
    int findroot(int x)
    {
        if(x!=father[x])
            father[x]=findroot(father[x]);
        return father[x];
    }
    void setroot(int x,int y)
    {
        x=findroot(x);
        y=findroot(y);
        father[x]=y;
    }
    int main()
    {
        int cas = 1;
        int n,m,i,j;
        EDG edg[305];
        while(~scanf("%d%d",&n,&m))
        {
            for(int i=0;i<=n;i++)
                father[i]=i;
    
            int cnt = 0;
            for(i =1;i<=n;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
            for( i=1;i<=m;i++)
                scanf("%d%d",&edg[i].u,&edg[i].v);
    
            for(i = 1;i<=m;i++)
            {
                setroot(edg[i].u,edg[i].v);
                for(j =1;j<i;j++)
                {
                    if(is(p[edg[i].u],p[edg[i].v],p[edg[j].u],p[edg[j].v]))
                    {
                        setroot(findroot(edg[i].v),findroot(edg[j].v));
                    }
                }
            }
            for(i=1;i<=n;i++)
                if(father[i]==i)
                cnt++;
    
            printf("%s\n",cnt>1?"NO":"YES");
        }
    
        return 0;
    }
    


    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值