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;
}
原文地址:https://www.cnblogs.com/acm1ruoji/p/10726167.html