poj 1556 zoj1721 BellmanFord 最短路+判断直线相交

http://poj.org/problem?id=1556

The Doors

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 6120   Accepted: 2455

Description

You are to find the length of the shortest path through a chamber containing obstructing walls. The chamber will always have sides at x = 0, x = 10, y = 0, and y = 10. The initial and final points of the path are always (0, 5) and (10, 5). There will also be
from 0 to 18 vertical walls inside the chamber, each with two doorways. The figure below illustrates such a chamber and also shows the path of minimal length.

Input

The input data for the illustrated chamber would appear as follows.

2

4 2 7 8 9

7 3 4.5 6 7

The first line contains the number of interior walls. Then there is a line for each such wall, containing five real numbers. The first number is the x coordinate of the wall (0 < x < 10), and the remaining four are the y coordinates of the ends of the doorways
in that wall. The x coordinates of the walls are in increasing order, and within each line the y coordinates are in increasing order. The input file will contain at least one such set of data. The end of the data comes when the number of walls is -1.

Output

The output should contain one line of output for each chamber. The line should contain the minimal path length rounded to two decimal places past the decimal point, and always showing the two decimal places past the decimal point. The line should contain no
blanks.

Sample Input

1
5 4 6 7 8
2
4 2 7 8 9
7 3 4.5 6 7
-1

Sample Output

10.00
10.06

Source

Mid-Central USA 1996

开始的时候真的是二逼了,

1、判断相交的函数写错了,我居然判断的是是不是跟源点和终点的直线相交。。。二逼啊,,,

2、然后改了之后还wa,因为判断里少了个!,,,,没取反,,,

3、极限的点,比如每道墙的最上沿和最下沿,这两个点不可达,就是说从源头到终点不能经过这两个点,开始的时候没排除,虽然那样的话也能AC,还是题目数据太弱了啊

我自己写的判断直线相交的模板:

/*==========================================================*||  判断点在直线上或直线相交
    1、函数值为0,表示在直线上;
    2、test(a,b,t1)*test(a,b,t2)<0表示直线ab和直线t1t2相交
\*==========================================================*/
double test(Point a,Point b, Point t)
{
    return (b.y-a.y)*(t.x-b.x)-(b.x-a.x)*(t.y-b.y);
}

思路还是比较顺的,就是最短路+判断直线相交

贴代码:

#include<cstdio>
#include<cstring>
#include <string>
#include <map>
#include <iostream>
#include <cmath>
using namespace std;
#define INF 10000
const double eps=1e-6;

const int MAXN = 1011;
#define Max(a,b) (a)>(b)?(a):(b)
int cntp;
int wn;
struct Point{
    Point(double x=0,double y=0):x(x),y(y){}
    double x,y;
    int id;
}p[MAXN];
struct Wall{
    double s1,e1;
    double s2,e2;
    double s3;
}w[20];//=0~~=wn
double e[MAXN][MAXN],dist[MAXN];

double dis(Point a, Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

void init()
{
    cntp=1;
    for(int i=0;i<=MAXN;i++)
        for(int j=0;j<=MAXN;j++)
        {
            if(i == j)e[i][j]=0;
            else e[i][j]=INF;
        }
    p[0].x=0,p[0].y=5,p[0].id=0;
    for(int i=0;i<=MAXN;i++)dist[i]=INF;
}

double test(Point a,Point b, Point t)
{
    return (b.y-a.y)*(t.x-b.x)-(b.x-a.x)*(t.y-b.y);
}

bool Judge(Point a, Point b)
{
    if(a.id>b.id)
    {
        Point t=a;
        a=b;
        b=t;
    }
    //int flag=1;
    if(a.id>0)
        if(a.y -0.0 <=eps||10.0-a.y <=eps)
            return 0;
    if(b.id<cntp-1)
        if(b.y-0.0<=eps || 10.0-b.y<=eps)
            return 0;

    for(int i=a.id+1;i<b.id;i++)
    {
        Point p1(w[i].s1,w[i].e1),p2(w[i].s1,w[i].s2),p3(w[i].s1,w[i].e2),p4(w[i].s1,w[i].s3);

        if(!(
             test(a,b,p1)*test(a,b,p2)<0 ||
            test(a,b,p3)*test(a,b,p4)<0)
           )return 0;
    }
        /*for(int i=a.id+1;i<b.id;i++)
        {
            if(!(
                 (w[i].e1<5.0&&w[i].s2>5.0)
                || (w[i].e2<5.0&&w[i].s3>5.0)
                 )
               )return 0;
        }*/
    return 1;
}

void Build()
{
    for(int i=0;i<cntp;i++)
    {
        for(int j=i+1;j<cntp;j++)
        {
            //if(i == j)continue;
            if(p[i].id == p[j].id)continue;

            if(Judge(p[i],p[j]))
            {
                e[i][j]=min(e[i][j],dis(p[i],p[j]));
            }
        }
    }
}

void Bellman(int v0)
{
    int n=cntp;
    for(int i=0;i<cntp;i++)
    {
        dist[i]=e[v0][i];
        //if(i!=v0 && dist[i]<INF)
    }
    for(int k=2;k<n;k++)
    {
        for(int u=0;u<n;u++)
        {
            if(u!=v0)
            {
                for(int j=0;j<n;j++)
                {
                    if(e[j][u]!=INF && dist[j]+e[j][u]<dist[u])
                    {
                        dist[u]=dist[j]+e[j][u];
                    }
                }
            }
        }
    }
}

int main()
{
      //  freopen("poj1556.txt","r",stdin);
       while(~scanf("%d",&wn) && ~wn)
       {
           init();
           for(int i=1;i<=wn;i++)
           {
                scanf("%lf%lf%lf%lf%lf",&w[i].s1,&w[i].e1,&w[i].s2,&w[i].e2,&w[i].s3);
                p[cntp].id=p[cntp+1].id=p[cntp+2].id=p[cntp+3].id=p[cntp+4].id=p[cntp+5].id=i;
                p[cntp].x=p[cntp+1].x=p[cntp+2].x=p[cntp+3].x=p[cntp+4].x=p[cntp+5].x=w[i].s1;
                p[cntp].y=0.0,p[cntp+1].y=w[i].e1,p[cntp+2].y=w[i].s2,p[cntp+3].y=w[i].e2,p[cntp+4].y=w[i].s3,p[cntp+5].y=10.0;
                ////////////////
                //e[cntp+1][cntp+2]=w[i].s2-w[i].e1;
               // e[cntp+3][cntp+4]=w[i].s3-w[i].e2;
                cntp+=6;
           }
           p[cntp].x=10.0,p[cntp].y=5.0,p[cntp].id=++wn;
           cntp++;
           //if()
           Build();
           Bellman(0);
           printf("%.2lf\n",dist[cntp-1]);
           ///////////////////
          // for(int i=0;i<cntp;i++)
          //  printf("%d %lf\n",i,dist[i]);
       }
       return 0;
}

poj 1556 zoj1721 BellmanFord 最短路+判断直线相交

时间: 2024-10-13 00:07:58

poj 1556 zoj1721 BellmanFord 最短路+判断直线相交的相关文章

[ACM] POJ 3259 Wormholes (bellman-ford最短路径,判断是否存在负权回路)

Wormholes Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29971   Accepted: 10844 Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way p

POJ 1269 Intersecting Lines(判断直线相交)

题目地址:POJ 1269 直接套模板就可以了...实在不想自己写模板了...写的又臭又长....不过这题需要注意的是要先判断是否有直线垂直X轴的情况. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include <ctype.h>

Jack Straws(并差集和判断直线相交问题)

Jack Straws Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 3155   Accepted: 1418 Description In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the table and players try to remove them one-by-one witho

[poj] 1066 Treasure Hunt || 判断直线相交

原题 在金字塔内有一个宝藏p(x,y),现在要取出这个宝藏. 在金字塔内有许多墙,为了进入宝藏所在的房间必须把墙炸开,但是炸墙只能炸每个房间墙的中点. 求将宝藏运出城堡所需要的最小炸墙数. 判断点和直线相交. 枚举每道墙的两个端点和p的连线这条线段和墙的交点的次数最小值即为需要炸墙的最小次数. [注意当墙数为零时输出1:] #include<cstdio> #include<algorithm> #define N 33 using namespace std; int ans=0

POJ 1269 Intersecting Lines【判断直线相交】

题意:给两条直线,判断相交,重合或者平行 思路:判断重合可以用叉积,平行用斜率,其他情况即为相交. 求交点: 这里也用到叉积的原理.假设交点为p0(x0,y0).则有: (p1-p0)X(p2-p0)=0 (p3-p0)X(p2-p0)=0 展开后即是 (y1-y2)x0+(x2-x1)y0+x1y2-x2y1=0 (y3-y4)x0+(x4-x3)y0+x3y4-x4y3=0 将x0,y0作为变量求解二元一次方程组. 假设有二元一次方程组 a1x+b1y+c1=0; a2x+b2y+c2=0

POJ 3304 Segments (叉乘判断线段相交)

<题目链接> 题目大意: 给出一些线段,判断是存在直线,使得该直线能够经过所有的线段.. 解题思路: 如果有存在这样的直线,过投影相交区域作直线的垂线,该垂线必定与每条线段相交,问题转化为问是否存在一条线和所有线段相交. 如果存在这么一条直线,那么该直线一定能够移成经过两个端点的形式.枚举所有线段的两个端点,判断该直线和所有线段是否相交即可. #include <iostream> #include <math.h> #include <cstdio> us

poj 1127(直线相交+并查集)

Jack Straws Description In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the table and players try to remove them one-by-one without disturbing the other straws. Here, we are only concerned with if various pairs o

Poj 1556 The Doors 计算几何+最短路

其实本题非常的无脑,无脑拍完1A,写到blog里只因为TM无脑拍也拍了很久啊= = #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdl

判断线段和直线相交 POJ 3304

1 // 判断线段和直线相交 POJ 3304 2 // 思路: 3 // 如果存在一条直线和所有线段相交,那么平移该直线一定可以经过线段上任意两个点,并且和所有线段相交. 4 5 #include <cstdio> 6 #include <cstring> 7 #include <iostream> 8 #include <algorithm> 9 #include <map> 10 #include <set> 11 #inclu