1. 程式人生 > >牛客國慶集訓派對Day1 L New Game!

牛客國慶集訓派對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;
}