1. 程式人生 > >UPC-9519 New Game 前向星+Dijkstra演算法

UPC-9519 New Game 前向星+Dijkstra演算法

題目傳送門

AC程式碼:(其實我也看不懂= =)

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1e6+7;
struct Edge{
    int nex,to;
    double w;
}edge[maxn];
int head[maxn];
bool vis[maxn];
int cnt=0;
double dis[maxn];
int  a,b,c1,c2;
int  x[maxn],y[maxn],r[maxn];
int n;
inline void add(int u,int v,double w){
    edge[cnt].to=v;
    edge[cnt].w=w;
    edge[cnt].nex=head[u];
    head[u]=cnt++;
}
inline void read(int&x) {
    int f=1;x=0;char c=getchar();
    while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+c-48,c=getchar();}
    x=x*f;
}
 
typedef pair<double, int> P;
 
void dij(int s){
    priority_queue<P ,vector<P>,greater<P> >q;
    memset(vis,0,sizeof vis);
    for(int i=0;i<n+2;i++)
        dis[i]=(double)1e18;
    dis[s] = 0;
    q.push(P(0,s));
    while (!q.empty()){
        P p = q.top();
        q.pop();
        int u = p.second;
        if(vis[u])continue;
        vis[u] = 1;
        for(int i = head[u];~i;i=edge[i].nex){
            int v = edge[i].to;
            double w = edge[i].w;
            if(dis[v]>dis[u]+w&&!vis[v]){
                dis[v] = dis[u]+w;
                q.push(P(dis[v],v));
            }
        }
    }
 
}
int main()
{
    scanf("%d%d%d%d%d",&n,&a,&b,&c1,&c2);
    for(int i=1;i<=n;i++)
        scanf("%d%d%d",&x[i],&y[i],&r[i]);
    cnt=0;
    memset(head,-1,sizeof head);
    double t=abs(c1-c2)/sqrt(a*a+b*b);
    add(0,n+1,t);
//    mp[0].push_back(make_pair(0,0));
    add(n+1,0,t);
//    mp[n+1].push_back(make_pair(n+1,0));
    for(int i=1;i<=n;i++)
    {
        double t1=abs(a*x[i]+b*y[i]+c1)/sqrt(a*a+b*b)-r[i];
        if(t1<0) t1=0;
        add(i,0,t1);
        add(0,i,t1);
        double t2=abs(a*x[i]+b*y[i]+c2)/sqrt(a*a+b*b)-r[i];
        if(t2<0) t2=0;
        add(n+1,i,t2);
        add(i,n+1,t2);
    }
    for(int i=1;i<=n;i++)
    {
//        mp[i].push_back(make_pair(i,0));
        for(int j=i+1;j<=n;j++)
        {
            double t3=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]))-r[i]-r[j];
            if(t3<0) t3=0;
            add(i,j,t3);
            add(j,i,t3);
        }
    }
    dij(0);
    printf("%.6f\n",dis[n+1]);
    return 0;
}