【Luogu】P2498拯救小云公主(spfa)
我水爆了- -
容易发现可以把两个圆之间连边,左上为起点右下为终点,最小生成树直到起点跟终点连起来,输出边权/2就行。
然后80.
并不理解为什么这可以转化成spfa求最短路,邻接矩阵暴力跑一下就AC了。
#include<cstdio> #include<algorithm> #include<cctype> #include<cstring> #include<cstdlib> #include<queue> #include<cmath> #define maxn 3030 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } struct Node{ double x,y; }; inline double calc(Node a,Node b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } Node q[maxn]; struct Edge{ int from,to; double val; bool operator <(const Edge a)const{ return val<a.val; } }d[maxn*maxn]; int cnt; double dis[maxn]; bool vis[maxn]; double mp[maxn][maxn]; int main(){ int e=read(),n=read(),m=read(); int up=e+1,down=e+2,left=e+3,right=e+4; for(int i=1;i<=right;++i) for(int j=1;j<=right;++j) mp[i][j]=0x7ffffffff; for(int i=1;i<=e;++i) q[i]=(Node){read(),read()}; for(int i=1;i<=e;++i){ for(register int j=i+1;j<=e;++j) mp[i][j]=mp[j][i]=calc(q[i],q[j]); mp[up][i]=(n-q[i].x)*2; mp[i][down]=(q[i].x-1)*2; mp[left][i]=(q[i].y-1)*2; mp[i][right]=(m-q[i].y)*2; } queue<int>f; f.push(up); f.push(left); for(int i=1;i<=right;++i) dis[i]=0x7ffffffff; dis[up]=dis[left]=0; while(!f.empty()){ int from=f.front();f.pop(); vis[from]=0; for(int to=1;to<=right;++to){ if(max(mp[from][to],dis[from])<dis[to]){ dis[to]=max(mp[from][to],dis[from]); if(vis[to]) continue; vis[to]=1; f.push(to); } } } printf("%.2lf\n",min(dis[down],dis[right])/2.0); return 0; }