POJ 1556 The Doors (線段相交+Dijkstra)

來源:互聯網
上載者:User

題意:找從起點到終點的最短路徑。

題解:可以知道,但凡兩點不能直達,則一定是沿著牆邊界點走的,這樣才能保證路徑最短。那麼只需要再所有可以直達的點間連上一條邊,求一次最短路徑。注意判斷兩線段是否相交應該是判斷“嚴格相交”,即不包含端點。

#include <cmath>#include <cstdio>/*#include <iostream>  //不知道為什麼加上這兩句就報一些奇怪的錯誤····using namespace std; */#define MAX 500#define eps 1e-8#define INF 999999999999#define zero(x) ( ((x) > 0 ? (x) : -(x)) < eps )struct Point { double x, y;};struct Line { Point a, b;};Point point[MAX];Line line[MAX];double dis[MAX], edge[MAX][MAX];bool vis[MAX];double xmult ( Point p1, Point p2, Point p0 )  // 叉積{return (p1.x-p0.x)*(p2.y-p0.y) - (p2.x-p0.x)*(p1.y-p0.y);}bool oPointosite_side ( Point p1, Point p2, Point l1, Point l2 ) // 判斷同側或者異側{return xmult(l1,p1,l2) * xmult(l1,p2,l2) < -eps;}bool intersect_ex ( Point u1, Point u2, Point v1, Point v2 ) // 判斷是否相交{return oPointosite_side(u1,u2,v1,v2) && oPointosite_side(v1,v2,u1,u2);}double distance ( Point p1, Point p2 ) // 求兩點間的距離{return sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y));}bool check ( int lnum, Point p1, Point p2 )  // 對於任意兩個點i,j,枚舉所有的邊,若它不與任意邊相交,則返回true{for ( int i = 1; i <= lnum; i++ ){if ( intersect_ex ( p1, p2, line[i].a, line[i].b ) )return false;}return true;}void build_map ( int pnum, int lnum ){int i, j;for ( i = 0; i < pnum; i++ )for ( j = i + 1; j <= pnum; j++ )edge[i][j] = edge[j][i] = INF;for ( i = 0; i < pnum; i++ ){for ( j = i + 1; j <= pnum; j++ )if ( check ( lnum, point[i], point[j] ) ) // 若 i, j 之間沒有牆壁阻擋,則可連一條邊edge[i][j] = edge[j][i] = distance ( point[i], point[j] );}}double Dijkstra ( int pnum ){int i, j, k;for ( i = 0; i <= pnum; i++ ){dis[i] = edge[0][i];vis[i] = 0;}vis[0] = true;dis[0] = 0;for ( i = 1; i <= pnum; i++ ){double minc = INF;for ( j = 0; j <= pnum; j++ ){if ( ! vis[j] && minc > dis[j] ){minc = dis[j];k = j;}}if ( minc == INF ) break;vis[k] = true;dis[k] = minc;for ( j = 0; j <= pnum; j++ ){if ( ! vis[j] && dis[j] > dis[k] + edge[k][j] )dis[j] = dis[k] + edge[k][j];}}return dis[pnum];}int main(){int n;while ( scanf("%d",&n) ){if ( n == -1 ) break;double x, y1, y2, y3, y4;int i, p = 0, l = 0;point[0].x = 0; point[0].y = 5; // 0 為起點for ( i = 1; i <= n; i++ ){scanf("%lf %lf %lf %lf %lf", &x, &y1, &y2, &y3, &y4 );l++;line[l].a.x = line[l].b.x = x;line[l].a.y = 0; line[l].b.y = y1;l++;line[l].a.x = line[l].b.x = x;line[l].a.y = y2; line[l].b.y = y3;l++;line[l].a.x = line[l].b.x = x;line[l].a.y = y4; line[l].b.y = 10;p++;point[p].x = x; point[p].y = y1;p++;point[p].x = x; point[p].y = y2;p++;point[p].x = x; point[p].y = y3;p++;point[p].x = x; point[p].y = y4;}p++;point[p].x = 10; point[p].y = 5; // p 為終點build_map ( p, l );double res = Dijkstra ( p );printf("%.2lf\n",res);}return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.