zoukankan      html  css  js  c++  java
  • poj 1556 The Doors 线段相交判断+最短路

    求点(0,5)到(10,5)的最短距离。
    图中任意两点(x座标不同)连线若没有与墙相交,则求出两点之间的距离加入最短路矩阵中,否则为无穷大。接下来用 dijkstra法求最短路即可。本题主要建图比较繁琐一点。
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<iostream>
    #include<cmath>
    using namespace std;
    struct point
    {
    double x,y;
    };
    struct line
    {
    point a,b;
    };
    struct door
    {
    double x,q[4];
    }p[2000];
    double multi(point p0,point p1,point p2)
    {
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    }
     
    bool is(point s1,point e1,point s2,point e2) //判断线段是否相交 
    {
    return (max(s1.x,e1.x)>=min(s2.x,e2.x))&&
      (max(s2.x,e2.x)>=min(s1.x,e1.x))&&
      (max(s1.y,e1.y)>=min(s2.y,e2.y))&&
      (max(s2.y,e2.y)>=min(s1.y,e1.y))&&
      (multi(s1,s2,e1)*multi(s1,e1,e2)>0)&&
      (multi(s2,s1,e2)*multi(s2,e2,e1)>0);
    }
    double dis(point p1,point p2)
    {
    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
    }
     
    int sink;
    double di[2000],flow[2000][2000];
    bool flag[2000];
    void dijkstra()
    {
         int i,j,v;
    double min;
       
            memset(flag,true,sizeof(flag));  
            flag[0]=false;
            for(i=0;i<=sink;i++)
                di[i]=flow[0][i];
            for(i=0;i<sink;i++)
            {
               min=99999;
               for(j=0;j<=sink;j++)
               {
                   if(flag[j]==true&&min>di[j])
                   {
                       min=di[j];
                       v=j;
                   }
               }
               flag[v]=false;
              
               for(j=0;j<=sink;j++)
               {
                   if(flag[j]==true&&di[j]>flow[v][j]+di[v])
                   di[j]=flow[v][j]+di[v];
               }
            }
    }
    int main()
    {
    int m,n,x,i,j,k,h,flag1;
    point s1,e1,s2,e2;
    while(scanf("%d",&n),n!=-1)
    {
    for(i=1;i<=n;i++)
    scanf("%lf%lf%lf%lf%lf",&p[i].x,&p[i].q[0],&p[i].q[1],&p[i].q[2],&p[i].q[3]);
        for(i=0;i<=4*n+1;i++)
        for(j=0;j<=4*n+1;j++)
        flow[i][j]=99999;
    for(i=0;i<=n;i++)
    for(k=0;k<4;k++)
    {
    if(i==0&&k>0)
    break;
    for(j=i+1;j<=n+1;j++)
    {
    for(h=0;h<4;h++)
    {
    if(j==n+1&&h>0)
    break;
    if(i==0)
    {
    s1.x=0;s1.y=5;
    }
    else
    {
    s1.x=p[i].x;
    s1.y=p[i].q[k];
    }
    if(j==n+1)
    {
    e1.x=10;
    e1.y=5;
    }
    else
    {
    e1.x=p[j].x;
    e1.y=p[j].q[h];
    }
    flag1=1;
    for(m=i+1;m<j;m++)
    {
    e2.x=p[m].x;e2.y=0;
    s2.x=p[m].x;s2.y=p[m].q[0];
    if(is(s1,e1,s2,e2))
    flag1=0;
    e2.y=p[m].q[1];
    s2.y=p[m].q[2];
    if(is(s1,e1,s2,e2))
    flag1=0;                               
    e2.y=10;
    s2.y=p[m].q[3];
    if(is(s1,e1,s2,e2))
    flag1=0;
        if(flag1==0)
        break;
    }
    if(flag1)
    {
    if(i==0)
    {
    flow[4*(j-1)+h+1][0]=flow[0][4*(j-1)+h+1]=dis(s1,e1);
    }
    else
    {
    flow[4*(j-1)+h+1][4*(i-1)+k+1]=flow[4*(i-1)+k+1][4*(j-1)+h+1]=dis(s1,e1);
    }
        }
    }
    }
    }
    sink=4*n+1;
    dijkstra();
    printf("%.2f\n",di[4*n+1]);
    }
    }
     
     
     
     
     
  • 相关阅读:
    POJ2823 Sliding Window【双端队列】
    初识Identity
    dSploitzANTI渗透教程之启动zANTI工具
    dSploitzANTI渗透教程之安装zANTI工具
    iOS Sprite Kit教程之滚动场景
    iOS Sprite Kit教程之场景的切换
    iOS Sprite Kit教程之场景的设置
    iOS Sprite Kit教程之真机测试以及场景的添加与展示
    iOS Sprite Kit教程之申请和下载证书
    iOS Sprite Kit教程之使用帮助文档以及调试程序
  • 原文地址:https://www.cnblogs.com/zxj015/p/2740226.html
Copyright © 2011-2022 走看看