牛客國慶集訓派對Day1 L New Game!(最短路spfa)
阿新 • • 發佈:2018-12-13
差一點就在一條錯誤的方向越走越遠了
竟然是最短路 太強了
#include<bits/stdc++.h> using namespace std; const int maxn=1e3+10; const int N=1e6+100; const int inf=0x3f3f3f3f; const double eps=1e-6; int a,b,c1,c2; int n; int x[maxn],y[maxn],r[maxn]; int head[N]; struct node { int u,v,next; double w; }e[N]; int cnt=0; int s,t; void addedge(int u,int v,double w) { ++cnt; e[cnt].u=u; e[cnt].v=v; e[cnt].w=w; e[cnt].next=head[u]; head[u]=cnt; ++cnt; e[cnt].u=v; e[cnt].v=u; e[cnt].w=w; e[cnt].next=head[v]; head[v]=cnt; } double yuan(int a,int b) { double ans=sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b])); ans=ans-r[a]-r[b]; ans=max(0.0,ans); return ans; } double dis2(int k,int a,int b,int c) { double d=fabs(1.0*(a*x[k]+b*y[k]+c)/sqrt(a*a+b*b)); d-=r[k]; d=max(d,0.0); return d; } int vis[maxn]; double dis[maxn]; double spfa() { for(int i=0;i<=n+1;i++) dis[i]=inf; memset(vis,0,sizeof(vis)); dis[0]=0; vis[0]=1; queue<int>q; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].v; double w=e[i].w; if(dis[v]>dis[u]+w) { //cout<<v<<' '<<w<<endl; dis[v]=dis[u]+w; if(!vis[v]) { q.push(v); vis[v]=1; } } } } return dis[t]; } int main() { memset(head,-1,sizeof(head)); 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]); } for(int i=1;i<=n;i++) { addedge(0,i,dis2(i,a,b,c1)); addedge(i,n+1,dis2(i,a,b,c2)); for(int j=i+1;j<=n;j++) { addedge(i,j,yuan(i,j)); } } addedge(0,n+1,fabs((c1-c2)/sqrt(a*a+b*b))); s=0,t=n+1; double ans=spfa(); printf("%.6lf\n",ans); return 0; }