牛客国庆集训派对Day1 L New Game!

这个题是一个最短路的练习;

我们将每一个圆心看成一个连接点,将他们的路径连接起来,求距离的时候需要注意(在圆内,圆上,线上它们的距离是0)

当两个圆相离它们的距离就是两点之间的距离减去两点的半径,如果是一个负值说明两个圆是相交的,那么它们的距离就是0;

剩下的就是一个spfa解决这个问题;

代码如下:

#include <bits/stdc++.h>

#define maxn 100005

typedef long long ll;

using namespace std;

struct cir
{
    double x;
    double y;
    double r;
}
mapp[maxn];

struct node
{
    ll xx;
    double step;
    node(ll xxx,double yy):xx(xxx),step(yy){}
};
bool operator <(const node a,const node b)
{
    return a.step > b.step;
}
ll n;
vector<pair<ll,double> >p[maxn];
priority_queue<node>q;
double dis[maxn];
ll flag[maxn];
void spfa()
{
    for(int i = 1; i <= n + 1; i ++) dis[i]=2147483647;
    dis[0] = 0;
    q.push(node(0,0.0));
    while(!q.empty())
    {
        node kk = q.top();
        q.pop();
        flag[kk.xx] = 1;
        if(kk.step != dis[kk.xx])continue;
        for(int i = 0; i < p[kk.xx].size(); i ++)
        {
            ll to = p[kk.xx][i].first;
            if(!flag[to] && dis[to] > dis[kk.xx] + p[kk.xx][i].second)
            {
                dis[to] = dis[kk.xx] + p[kk.xx][i].second;
                q.push(node(to,dis[to]));
            }
        }
    }
}
int main()
{
    double a,b,c1,c2,tep;
    cin >> n >> a >> b >> c1 >> c2;
    for(int i = 1; i <= n; i ++)
    {
        cin >> mapp[i].x >> mapp[i].y >> mapp[i].r;
        tep = max(fabs((a * mapp[i].x + b * mapp[i].y + c1) / sqrt(a * a + b * b)) - mapp[i].r,0.0);
        p[0].push_back(make_pair(i,tep));
        p[i].push_back(make_pair(0,tep));
        tep = max(fabs((a * mapp[i].x + b * mapp[i].y + c2) / sqrt(a * a + b * b)) - mapp[i].r,0.0);
        p[n+1].push_back(make_pair(i,tep));
        p[i].push_back(make_pair(n+1,tep));
    }

    for(int i = 1; i <= n; i ++)
    {
        for(int j = i + 1; j <= n; j ++)
        {
            tep = max(sqrt((mapp[i].x - mapp[j].x) * (mapp[i].x - mapp[j].x) + (mapp[i].y - mapp[j].y) * (mapp[i].y - mapp[j].y)) - mapp[i].r - mapp[j].r,0.0);
            p[i].push_back(make_pair(j,tep));
            p[j].push_back(make_pair(i,tep));
        }
    }

    spfa();

    cout << fixed << setprecision(6) << dis[n+1] << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zzzanj/article/details/82927314