BOJ1509 海边 dijstra 最短路

来源:互联网 发布:情趣用品,淘宝免费代理 编辑:程序博客网 时间:2024/04/29 15:27

题意:这题题目写得够坑的。前面一大串都是无关信息。

其实很简单,就是在二维坐标里面给出若干个圆(阴影),给出起始点和终止点。

问从起始点到终止点,怎么走可以使暴露在非阴影下的路径最短。输出最短路的值。


思路:其实很简单,刚一看,设计到圆面积感觉比较有点蒙,其实圆可以当成点来处理,如果要进去某个圆。

则朝着这个圆的圆心的直线方向走肯定是最短。所以就可以抽象成一个图。每个圆也是一个点。

点与点的路径和圆半径有关,构图时候注意一下即可。

然后dijstra算法。


#include<iostream>//#include<stdio.h>#include<math.h>//#include<memory.h>//#define min(a,b) (a<b?a:b)//#define max(a,b) (a>b?a:b)using namespace std;const int N=1005;const double inf=40000.0;double mat[N][N];int n;struct Node{    double x;double y;}s,t;struct Node2{    double x,y,r;}circle[N];double dis[N];bool vis[N];void dij(){    memset(vis,0,sizeof(vis));    for(int i=0;i<=n+1;i++)        dis[i]=inf;    dis[0]=0.0;    vis[0]=true;    int now=0;    for(int i=1;i<=n+1;i++)    {        double mn=inf;        int k=-1;        for(int j=1;j<=n+1;j++)        {            if(!vis[j])            {                if(mat[now][j]!=inf&&mat[now][j]+dis[now]<dis[j])                {                    dis[j]=mat[now][j]+dis[now];                }                if(dis[j]<mn)                    mn=dis[j],k=j;            }        }        now=k;        vis[now]=true;        if(now==n+1)        {                printf("%.3lf\n",dis[n+1]);            break;        }    }    }void solve(){    for(int i=1;i<=n;i++)    {        mat[0][i]=mat[i][0]=sqrt((circle[i].x-s.x)*(circle[i].x-s.x)+(circle[i].y-s.y)*(circle[i].y-s.y))-circle[i].r;        if(mat[0][i]<0.0)            mat[0][i]=mat[i][0]=0.0;        mat[n+1][i]=(mat[i][n+1]=sqrt((circle[i].x-t.x)*(circle[i].x-t.x)            +(circle[i].y-t.y)*(circle[i].y-t.y))-circle[i].r);        if(mat[n+1][i]<0.0)            mat[n+1][i]=mat[i][n+1]=0.0;        for(int j=i+1;j<=n;j++)        {            mat[i][j]=mat[j][i]=(sqrt((circle[i].x-circle[j].x)*(circle[i].x-circle[j].x)+(circle[i].y-circle[j].y)*(circle[i].y-circle[j].y))-circle[i].r-circle[j].r);            if(mat[i][j]<0.0)                mat[i][j]=mat[j][i]=0.0;        }    }    mat[0][n+1]=mat[n+1][0]=sqrt((t.x-s.x)*(t.x-s.x)+(t.y-s.y)*(t.y-s.y));    dij();}int main(){        int cases;    scanf("%d",&cases);    while(cases--)    {        scanf("%d",&n);        memset(circle,0,sizeof(circle));        for(int i=0;i<=n+1;i++)            for(int j=0;j<=n+1;j++)                mat[i][j]=inf;        scanf("%lf%lf%lf%lf",&s.x,&s.y,&t.x,&t.y);        for(int i=1;i<=n;i++)        {            scanf("%lf%lf%lf",&circle[i].x,&circle[i].y,&circle[i].r);        }        solve();    }}

原创粉丝点击