HLG 1450 Farmer John【线段相交判断+最短路】

题意: 给一个起点和一个终点,然后给出 N 个互不相交的栅栏,问从起点到终点如果不穿过栅栏(可以接触)最少需要走多

        远的距离。

分析: 如果两个点所在线段,没有其它线段与之相交,则可以在两点之间连一条线段,最后只要求出起点到终点的最短距离即可,

    时间复杂度O(N^3)

CODE :

View Code
#include<stdio.h>
#include<string.h>
#include<math.h>
double min(double a,double b){ return a<b?a:b; }
double max(double a,double b){ return a>b?a:b; }
const double eps=1e-10;
const double INF=9999999.0;
double g[205][205];
struct node
{
    double x,y;
}a[202],b[202];
double dis(node a,node b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int inter(node a,node b,node c,node d)     // 线段相交判断。。。
{
    if(min(a.x,b.x)>max(c.x,d.x)||
       min(a.y,b.y)>max(c.y,d.y)||
       min(c.x,d.x)>max(a.x,b.x)||
       min(c.y,d.y)>max(a.y,b.y)) 
       return 0;
    double h,i,j,k;
    h=(b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
    i=(b.x-a.x)*(d.y-a.y)-(b.y-a.y)*(d.x-a.x);
    j=(d.x-c.x)*(a.y-c.y)-(d.y-c.y)*(a.x-c.x);
    k=(d.x-c.x)*(b.y-c.y)-(d.y-c.y)*(b.x-c.x);
    return h*i<=eps&&j*k<=eps;
}
int n;
double dijkstra()
{
    int s[210];
    double dis[210];
    int i,j;
    memset(s,0,sizeof(s));
    for(i=0;i<=2*(n+1);i++)
        dis[i]=INF;
    for(i=0;i<=2*(n+1);i++)
        dis[i]=g[1][i];
    s[1]=1;
    int u,tmp;
    for(i=2;i<=2*(n+1);i++)
    {
        tmp=INF;
        u=1;
        for(j=1;j<=2*(n+1);j++)
            if((!s[j])&&dis[j]<tmp)
            {
                u=j;
                tmp=dis[j];
            }
        s[u]=1;
        for(j=1;j<=2*(n+1);j++)
            if((!s[j])&&g[u][j]<INF&&g[u][j]+dis[u]<dis[j])
                dis[j]=g[u][j]+dis[u];
    }
    return dis[n+1+1];
}
int main()
{
//freopen("D:data.in","r",stdin);
//freopen("D:ce.txt","r",stdin);
    int i,j,k,t,flag;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf%lf%lf%lf",&a[1].x,&a[1].y,&b[1].x,&b[1].y);
        scanf("%d",&n);
        if(n==0)
        {
            printf("%.6lf\n",dis(a[1],b[1]));
            continue;
        }
        for(i=2;i<=n+1;i++)
            scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&b[i].x,&b[i].y);
        for(i=0;i<=2*(n+1);i++)
            for(j=0;j<=2*(n+1);j++)
                g[i][j]=INF;
        for(i=1;i<=n+1;i++)               //  建图。。。
        {
            for(j=i+1;j<=n+1;j++)
            {
                flag=0;    
                for(k=2;k<=n+1;k++)
                {
                    if(k==i||k==j)
                        continue;
                    if(inter(a[i],a[j],a[k],b[k]))
                    {
                        flag=1;
                        break;
                    }
                }
                if(!flag)
                    g[i][j]=g[j][i]=dis(a[i],a[j]);    
            }
            
            for(j=i;j<=n+1;j++)
            {
                flag=0;
                if(i==j&&i!=1)
                    continue;
                for(k=2;k<=n+1;k++)
                {
                    if(k==i||k==j)
                        continue;
                    if(inter(a[i],b[j],a[k],b[k]))
                    {
                        flag=1;
                        break;
                    }
                }
                if(!flag)
                    g[i][j+n+1]=g[j+n+1][i]=dis(a[i],b[j]);
                }
            for(j=i+1;j<=n+1;j++)
            {
                flag=0;
                for(k=2;k<=n+1;k++)
                {
                    if(k==i||k==j)
                        continue;
                    if(inter(b[i],a[j],a[k],b[k]))
                    {
                        flag=1;
                        break;
                    }
                }
                if(!flag)
                    g[i+n+1][j]=g[j][i+n+1]=dis(b[i],a[j]);
            }
            for(j=i+1;j<=n+1;j++)
            {
                flag=0;
                for(k=2;k<=n+1;k++)
                {
                    if(k==i||k==j)
                        continue;
                    if(inter(b[i],b[j],a[k],b[k]))
                    {
                        flag=1;
                        break;
                    }
                }
                if(!flag)
                    g[i+n+1][j+n+1]=g[j+n+1][i+n+1]=dis(b[i],b[j]);
            }
        }
        printf("%.6lf\n",dijkstra());
    }
    return 0;
} 

 

posted @ 2012-06-04 20:47  'wind  阅读(186)  评论(0编辑  收藏  举报