码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-04-19 22:53:32      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:图论

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;
}


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

标签:图论

原文地址:http://blog.csdn.net/u010372095/article/details/45133157

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!