dijkstra


傳送門:

題目已經寫的很清楚是最短路問題了,但是這是一個考幾何的最短路emmm,所以我把他放來綜合題。

題意:給出兩條平行線跟n個圓,然后在圓上走跟在線上走不消耗體力,求L1到L2的最短路

首先寫這道題需要反復用這兩個公式

平行線距離公式

 

我們很容易就能想到把整個圓看成一個點,然后去做最短路,那么我們就要加一個源點跟匯點,源點為L1,匯點為L2

 

然后枚舉算出所有圓到源點跟匯點的距離。再枚舉算出在圓與圓之間的最短路。

然后就可以開始我們愉快的dijstra了

代碼如下:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define P pair<int,int>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
const int N=1e6+10;
const int mod=19260817;
void read(int &a)
{
    a=0;
    int d=1;
    char ch;
    while(ch=getchar(),ch>'9'||ch<'0')
        if(ch=='-')
            d=-1;
    a=ch-'0';
    while(ch=getchar(),ch>='0'&&ch<='9')
        a=a*10+ch-'0';
    a*=d;
}
void write(int x)
{
    if(x<0)
        putchar(45),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+'0');
}
struct note
{
    int pos;
    double dis;
    bool operator < (const note &x) const
    {
        return x.dis<dis;
    }
};
int a[1005][5],n;
double l[1005][1005],dis[1005];
bool vis[1005];
priority_queue <note> q;
inline void dijstra(int st)
{
    memset(dis,126,sizeof(dis));
    dis[st]=0.0;
    q.push({st,0.0});
    while(!q.empty())
    {
        note x=q.top();
        q.pop();
        if(vis[x.pos])
           continue;
        vis[x.pos]=1;
        for(re int i=0;i<n+2;i++)
        {
            if(dis[i]>x.dis+l[x.pos][i])
                dis[i]=x.dis+l[x.pos][i],q.push({i,dis[i]});
        }
    }
}
int main()
{
    int A,B,C1,C2;
    read(n);
    read(A);
    read(B);
    read(C1);
    read(C2);
    for(re int i=0;i<n;i++)
        for(re int j=0;j<=2;j++)
            read(a[i][j]);
    int s=n,t=n+1;
    l[s][t]=l[t][s]=1.0*abs(C1-C2)/sqrt(((double)A*A+(double)B*B));
    for(re int i=0;i<n;i++)
    {
        l[s][i]=l[i][s]=max(0.0,1.0*abs((A*a[i][0]+B*a[i][1]+C1)/sqrt((double)A*A+(double)B*B))-a[i][2]);
        l[t][i]=l[i][t]=max(0.0,1.0*abs((A*a[i][0]+B*a[i][1]+C2)/sqrt((double)A*A+(double)B*B))-a[i][2]);
    }
    for(re int i=0;i<n;i++)
        for(re int j=0;j<n;j++)
            if(i!=j)
                l[i][j]=l[j][i]=max(0.0,1.0*sqrt((a[i][0]-a[j][0])*(a[i][0]-a[j][0])+(a[i][1]-a[j][1])*(a[i][1]-a[j][1]))-a[i][2]-a[j][2]);
    dijstra(s);
    cout<<dis[t]<<endl;
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM