【POJ】1556 The Doors 最短路+判断线段相交
2014-09-03 20:36
288 查看
传送门:【POJ】1556 The Doors
题目分析:状态太差了。。这题花了好久才写出来。。
题目倒是很简单,直接枚举边的起点u,终点v,看是否能够沿着直线从u走到v,如果可以则建边u-v,最后最短路即可。并且因为本题是DAG图,所以可以DP。
代码如下:
题目分析:状态太差了。。这题花了好久才写出来。。
题目倒是很简单,直接枚举边的起点u,终点v,看是否能够沿着直线从u走到v,如果可以则建边u-v,最后最短路即可。并且因为本题是DAG图,所以可以DP。
代码如下:
#include <cmath> #include <cstdio> #include <cstring> #include <algorithm> using namespace std ; #define REP( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define REV( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next ) #define CLR( a , x ) memset ( a , x , sizeof a ) const int MAXN = 1000 ; const int MAXE = 100000 ; const double eps = 1e-6 ; const double INF = 1e10 ; struct Point { double x , y ; Point () {} Point ( double x , double y ) : x ( x ) , y ( y ) {} Point operator - ( const Point& p ) const { return Point ( x - p.x , y - p.y ) ; } } p[MAXN] ; struct Edge { int v ; double c ; Edge* next ; } E[MAXE] , *H[MAXN] , *cur ; int n ; int Q[MAXN] , head , tail ; int in[MAXN] ; double d[MAXN] ; void clear () { cur = E ; CLR ( in , 0 ) ; CLR ( H , 0 ) ; } void addedge ( int u , int v , double c ) { cur -> v = v ; cur -> c = c ; cur -> next = H[u] ; H[u] = cur ++ ; } double Cross ( const Point& a , const Point& b ) { return a.x * b.y - a.y * b.x ; } double dist ( Point a ) { return sqrt ( a.x * a.x + a.y * a.y ) ; } bool Intersect ( Point a1 , Point a2 , Point b1 , Point b2 ) { if ( Cross ( a1 - a2 , b1 - a2 ) * Cross ( a1 - a2 , b2 - a2 ) <= eps ) return 1 ; return 0 ; } bool check ( Point a1 , Point a2 , int low , int high ) { REP ( i , low , high ) if ( !Intersect ( a1 , a2 , p[i * 4 + 1] , p[i * 4 + 2] ) && !Intersect ( a1 , a2 , p[i * 4 + 3] , p[i * 4 + 4] ) ) return 0 ; return 1 ; } void topo () { FOR ( i , 1 , n * 4 + 1 ) d[i] = INF ; head = tail = 0 ; FOR ( i , 0 , n * 4 + 1 ) if ( !in[i] ) Q[tail ++] = i ; d[0] = 0 ; while ( head != tail ) { int u = Q[head ++] ; travel ( e , H , u ) { int v = e -> v ; if ( -- in[v] == 0 ) Q[tail ++] = v ; if ( d[v] > d[u] + e -> c ) d[v] = d[u] + e -> c ; } } } void solve () { double x ; clear () ; p[0].x = 0 ; p[0].y = 5 ; p[n * 4 + 1].x = 10 ; p[n * 4 + 1].y = 5 ; REP ( i , 0 , n ) { scanf ( "%lf" , &x ) ; REP ( j , 1 , 5 ) { scanf ( "%lf" , &p[i * 4 + j].y ) ; p[i * 4 + j].x = x ; } } if ( check ( p[0] , p[n * 4 + 1] , 0 , n ) ) { printf ( "10.00\n" ) ; return ; } REP ( i , 0 , n ) { REP ( j , 1 , 5 ) { if ( check ( p[0] , p[i * 4 + j] , 0 , i ) ) { addedge ( 0 , i * 4 + j , dist ( p[0] - p[i * 4 + j] ) ) ; in[i * 4 + j] ++ ; } if ( check ( p[n * 4 + 1] , p[i * 4 + j] , i + 1 , n ) ) { addedge ( i * 4 + j , n * 4 + 1 , dist ( p[n * 4 + 1] - p[i * 4 + j] ) ) ; in[n * 4 + 1] ++ ; } REP ( k , i + 1 , n ) REP ( l , 1 , 5 ) if ( check ( p[i * 4 + j] , p[k * 4 + l] , i + 1 , k ) ) { addedge ( i * 4 + j , k * 4 + l , dist ( p[i * 4 + j] - p[k * 4 + l] ) ) ; in[k * 4 + l] ++ ; } } } topo () ; printf ( "%.2f\n" , d[n * 4 + 1] ) ; } int main () { while ( ~scanf ( "%d" , &n ) && ~n ) solve () ; return 0 ; }
相关文章推荐
- POJ 1556 The Doors(判断线段相交 && 最短路)
- POJ 1556 The Doors(判断线段相交 && 最短路)
- POJ 1556 The Doors (计算几何判断线段相交+最短路)
- POJ 1556 The Doors 最短路floyd + 判断两线段相交
- POJ 1556 The Doors 判断线段相交+最短路
- POJ_1556_The Doors_判断线段相交+最短路
- POJ 1556 The Doors 最短路floyd + 判断两线段相交
- poj 1556 The Doors(最短路+判断线段相交)
- poj 1556 The Doors(最短路+判断线段相交)
- poj 1556 The Doors 线段相交判断+最短路
- POJ-1556 线段相交的判断与最短路(几何+图论)
- poj 1556 The Doors(线段相交+最短路)
- 简单几何(线段相交+最短路) POJ 1556 The Doors
- 【POJ 1556】The Doors 判断线段相交+SPFA
- poj 1556 The Doors 线段相交,最短路
- poj 1556 The Doors(线段相交,最短路)
- POJ-1556 The Doors 线段相交+最短路
- poj 1556 The Doors (线段之间位置的判断+最短路)
- POJ 1556 计算几何 判断线段相交 最短路
- The Doors(poj1556线段相交+最短路径)