`
xxx0624
  • 浏览: 32151 次
文章分类
社区版块
存档分类
最新评论

POJ1556+线段相交

 
阅读更多
/*
dij+两点间距离
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<math.h>
using namespace std;

const int maxn = 205;//point number
const int maxm = 105;//line number
const double inf = 99999999;
const double eps = 1e-8;

struct POINT{
	double x,y;
	int f;
}S,T;

struct LINE{
	double x1,y1,x2,y2;
	int f;
};

int cnt_line,cnt_point;
POINT point[ maxn ];
LINE line[ maxm ];
double mat[ maxn ][ maxn ];

double dist( POINT a,POINT b ){
	double sum = (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
	return sqrt( sum );
}

 double xmult( POINT a,POINT b,POINT c ){
     return ( a.x-c.x )*( b.y-c.y )-( a.y-c.y )*( b.x-c.x );
 }
 
 bool inLine( LINE now,POINT p ){
     double minx,maxx,miny,maxy;
     minx=min( now.x1,now.x2 );
     maxx=max( now.x1,now.x2 );
     miny=min( now.y1,now.y2 );
     maxy=max( now.y1,now.y2 );
     if( p.x>=minx&&p.x<=maxx&&p.y>=miny&&p.y<=maxy )
         return true;
     else
         return false;
 }
 
bool Intersection( LINE one,LINE two ){
     double d1,d2,d3,d4;
     POINT t1,t2,t3,t4;
     t1.x = one.x1,t1.y = one.y1,t2.x = one.x2,t2.y = one.y2;
     t3.x = two.x1,t3.y = two.y1,t4.x = two.x2,t4.y = two.y2;
     d1=xmult( t3,t2,t1 );
     d2=xmult( t4,t2,t1 );
     d3=xmult( t1,t3,t4 );
     d4=xmult( t2,t3,t4 );
     if( d1*d2<0&&d3*d4<0 )
         return true;//相互跨过
     if( d1==0&&inLine( one,t3 )==true )
         return true;
     if( d2==0&&inLine( one,t4 )==true )
         return true;
     if( d3==0&&inLine( two,t1 )==true )
         return true;
     if( d4==0&&inLine( two,t2 )==true )
         return true;//分别表示某个点在一条直线上的情况
     return false;
 }

void init(){
	cnt_line = cnt_point = 0;
	for( int i=0;i<maxn;i++ ){
		for( int j=0;j<maxn;j++ ){
			mat[ i ][ j ] = inf;
		}
	}
}//init

void addline( double x1,double y1,double x2,double y2 ){
	line[ cnt_line ].x1=x1,line[ cnt_line ].y1=y1;
	line[ cnt_line ].x2=x2,line[ cnt_line ].y2=y2;
	cnt_line++;
}

void addpoint( double x,double y ){
	point[ cnt_point ].x = x;
	point[ cnt_point ].y = y;
	cnt_point++;
}

bool test( POINT a,POINT b ){
	LINE tt;
	tt.x1 = a.x,tt.y1 = a.y;
	tt.x2 = b.x,tt.y2 = b.y;
	//printf("a.flag:%d b.flag:%d\n",a.f,b.f);
	for( int i=0;i<cnt_line;i++ ){
		if( a.f!=line[ i ].f && b.f!=line[ i ].f && Intersection( tt,line[ i ] )==1 )
			return false;
	}
	return true;
}

double dij( int s,int t ){
	int vis[ maxn ];
	double dis[ maxn ];
	for( int i=0;i<cnt_point;i++ ){
		dis[ i ] = mat[ s ][ i ];
		vis[ i ] = 0;
	}
	dis[ s ] = 0;
	vis[ s ] = 1;
	//double sum = 0;
	for( int i=0;i<cnt_point;i++ ){
		int k;
		double tmax;
		k =-1,tmax = inf;
		for( int j=0;j<cnt_point;j++ ){
			if( vis[ j ]==0&&tmax>dis[ j ] ){
				tmax = dis[ j ];
				k=j;
			}
		}
		if( k==-1 ) break;
		vis[ k ] = 1;
		//sum += tmax;
		for( int j=0;j<cnt_point;j++ ){
			if( vis[ j ]==0&&dis[ j ]>dis[ k ]+mat[ k ][ j ] ){
				dis[ j ] = dis[ k ]+mat[ k ][ j ];
			}
		}
	}
	return dis[ t ];
}

int main(){
	int m;
	while( scanf("%d",&m),m!=-1 ){
		init();
		S.x = 0.0,S.y = 5.0;
		T.x = 10.0,T.y = 5.0;
		if( m==0 ){
			printf("%.2lf\n",dist( S,T ));
			continue;
		}
		int flag = 0;
		point[ cnt_point ].f = flag++;
		addpoint( S.x,S.y );
		point[ cnt_point ].f = flag++;
		addpoint( T.x,T.y );//start and end 
		double x,y1,y2,y3,y4;
		for( int num=1;num<=m;num++ ){
			scanf("%lf%lf%lf%lf%lf",&x,&y1,&y2,&y3,&y4);
			
			line[ cnt_line ].f = flag;
			addline( x,0.0,x,y1 );
			line[ cnt_line ].f = flag;
			addline( x,y2,x,y3 );
			line[ cnt_line ].f = flag;
			addline( x,y4,x,10.0 );//这三条线段归为一类
			
			point[ cnt_point ].f = flag;
			addpoint( x,y1 );
			point[ cnt_point ].f = flag;
			addpoint( x,y2 );
			point[ cnt_point ].f = flag;
			addpoint( x,y3 );
			point[ cnt_point ].f = flag;
			addpoint( x,y4 );//这四个点归为一类
			
			flag++;
		}
		//printf("flag:%d\ncnt_point:%d\ncnt_line:%d\n",flag,cnt_point,cnt_line);
		for( int i=0;i<cnt_point;i++ ){
			for( int j=i+1;j<cnt_point;j++ ){
				if( point[ i ].f!=point[ j ].f&&test( point[ i ],point[ j ] )==true ){
					mat[ i ][ j ] = mat[ j ][ i ] = dist( point[ i ],point[ j ] );
					//printf("mat[ %d ][ %d ] = %.2lf\n",i,j,mat[i][j]);
				}
			}
		}
		if( mat[ 0 ][ 1 ]!=inf ){
			printf("%.2lf\n",mat[ 0 ][ 1 ]);
			continue;
		}
		double ans = dij( 0,1 );
		printf("%.2lf\n",ans);
	}
	return 0;
}

分享到:
评论

相关推荐

    POJ1011-Sticks

    优化策略可能包括快速判断线段相交的方法,如Sweep Line算法或Segment Tree,以及并查集的路径压缩和按秩合并优化。 总结来说,"POJ1011 - Sticks"是一个锻炼程序员几何理解、图论应用和算法实现能力的好题目。它...

    线段直线相关题解1

    接着,只需要检查是否存在一条通过两个端点的直线能与所有其他线段相交。 第四题POJ3449是关于多边形和直线相交的复杂问题。我们需要处理不同类型的几何形状,如三角形、矩形等,以及它们之间的交点。对于每个图形...

    poj题目分类

    * 线段树:例如 poj2528、poj2828、poj2777、poj2886、poj2750。 * 静态二叉检索树:例如 poj2482、poj2352。 * 树状树组:例如 poj1195、poj3321。 * RMQ:例如 poj3264、poj3368。 * 并查集的高级应用:例如 ...

    ACM-POJ 算法训练指南

    2. **线段交**:计算线段是否相交及交点位置(poj3176, poj1080, poj1159)。 ### 七、概率统计 1. **概率计算**:计算随机事件的概率(POJ3252, poj1850, poj1019, poj1942)。 2. **期望值**:计算期望值问题...

    poj 2653代码 判断两直线是否相交

    题目"POJ 2653"是一个典型的计算几何问题,它的目标是编写程序来检查给定的一组直线(棍子)中哪些是相交的。 首先,我们需要了解计算几何中的基本数据结构和方法。在提供的代码中,`PointStruct`定义了表示二维...

    极角排序:POJ 1696(叉积+深搜)

    在计算几何中,叉积常用于判断点的位置关系、线段的相交情况等。深度优先搜索(Deepth-First Search, DFS)则是一种图或树遍历的方法,常用于解决复杂结构的搜索问题,如迷宫求解、有向图的拓扑排序等。 结合标签...

    POJ题目简单分类(ACM)

    - **叉积与点积**:辅助判断线段相交、点到线段距离等,如poj2031。 - **多边形算法**:如求面积、点在多边形内判定等,如poj1408。 - **凸包**:找到包含所有点的最小凸多边形,如poj2187。 这些知识点是ACM...

    acm新手刷题攻略之poj

    ### ACM新手刷题攻略之POJ ... - 推荐题目:[poj1860](https://vjudge.net/problem/POJ-1860)、[poj3259](https://vjudge.net/problem/POJ-3259)、[poj1062](https://vjudge.net/problem/POJ-1062)、[poj2253]...

    POJ 分类题目

    - **定义**:叉积和点积的应用,如线段相交判定、点到线段的距离等。 - **示例题目**: - poj2031 - poj1039 - **应用场景**:适用于几何图形的判断和计算。 **3. 多边型的算法** - **定义**:包括多边形的面积...

    强大的POJ分类——各类编程简单题及其算法分类

    2. **叉积和点积**:用于判断线段相交、计算距离等,如POJ2031和1039。 3. **多边形算法**:处理多边形的面积计算和相关判定,如点在多边形内、多边形是否相交,如POJ1408和1584。 4. **凸包**:找到图形的最小包围...

    ACMer需要掌握的算法讲解.docx

    3. 叉积和点积的运用(如线段相交的判定,点到线段的距离等) 六、动态规划 1. 需要用数据结构优化的动态规划 2. 四边形不等式理论 七、综合题 1. 组合数学 2. 博奕论 3. 对踵点 4. 杂题 八、附录 1. 哈希表、...

    北大POJ初级-计算几何学

    2. **线段与线段的关系**:如线段的长度、线段的交点判断,以及线段的排序和覆盖问题。 3. **圆与点、线的关系**:圆心、半径、点到圆的距离、线与圆的相交情况判断等。 4. **多边形**:包括简单多边形和复杂...

    【最新+免费】ACM主要算法.doc

    2. 叉积与点积:用于判断线段相交等问题。 3. 多边形:求面积和相关判定。 4. 凸包:如POJ 2187。 以上算法是ACM竞赛中初、中级阶段的重点,熟练掌握这些算法能够帮助你在比赛中取得更好的成绩。不断练习和深入理解...

    北大acm试题

    计算几何学是处理几何问题的数学分支,包括几何公式、叉积和点积的运用(如线段相交和点到线段距离的计算)、多边形算法(如求面积和判断点是否在多边形内)以及凸包问题。poj2031、poj1039、poj1408和poj1584等题目...

    参加ACM大赛应该准备哪些课程? (2).pdf

    5. 叉乘、判线段相交、凸包 6. BFS、DFS、hash表 7. 数学上的辗转相除、线段交点、多角形面积公式 数据结构 1. 线段树 2. 并查集 3. 动态规划的各个典型(LCS、最长递增子串、三角剖分、记忆化dp) 4. 博弈类算法...

    acm 分类 北大

    - 叉积和点积:用于判断线段相交和距离,如POJ1039。 - 多边形算法:计算面积和相关判定,如POJ1408。 - 凸包:找出一组点的最小凸包,如POJ2187。 这些知识点构成了ACM竞赛的基础,对于参赛者来说,理解和熟练...

    ACM算法总结大全——超有用!

    2. 叉积和点积:用于判断线段相交和距离计算,如poj2031、poj1039。 3. 多边形:求面积和相关判定,如poj1408、poj1584。 4. 凸包:找到一组点的最小凸包,如poj2187、poj1113。 中级阶段: 1. C++标准模板库的应用...

    ACM训练方案

    2. 叉积和点积:判断线段相交、点到线段距离等。 3. 多边形:求面积、点在多边形内和多边形相交判断。 4. 凸包:求解凸包问题。 中级阶段: 1. C++标准模板库的应用,如STL容器和算法。 2. 更复杂的模拟题:如poj...

    很快速的提高算法能力.docx

    - **叉积和点积**:用于判断线段相交、计算距离等,如Poj2031、Poj1039。 - **多边形算法**:包括求面积和相关判定,如Poj1408、Poj1584。 - **凸包**:学习计算和应用,如Poj2187、Poj1113。 8. **中级阶段:...

Global site tag (gtag.js) - Google Analytics