題意:一個人從直徑爲15米的小島上踩着鯊魚跳離湖(好奇怪的題目),湖爲100*100的正方形。人最大的跳躍距離爲D,給出n個鯊魚的座標,求人跳出島的最小距離及在這情況下的跳躍次數。
建圖有點麻煩
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<queue>
#include<math.h>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
struct Node{
double x,y;
}node[110];
int n;
double d;
double distlen(Node a,Node b){
return sqrt((a.x-b.x)*1.0*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)*1.0);
}
double mp[110][110];
int vis[110],pre[110];
double dist[110];
void spfa(int s,int t)
{
for(int i=0;i<=n+1;i++)
{
dist[i]=INF;
vis[i]=0;
pre[i]=-1;
}
queue<int> q;
q.push(s);
dist[s]=0;
vis[s]=1;
while(!q.empty())
{
int c=q.front();
q.pop();
vis[c]=0;
for(int i=0;i<=n+1;i++)
{
if(dist[i]>dist[c]+mp[c][i])
{
pre[i]=c;
dist[i]=dist[c]+mp[c][i];
if(!vis[i]) vis[i]=1,q.push(i);
}
}
}
if(dist[t]>=INF)
{
printf("can't be saved\n");
return;
}
int c=t,step=0;
while(c!=s)
step++,c=pre[c];
printf("%.2lf %d\n",dist[t],step);
return;
}
double _len(Node a,Node b){
return sqrt((a.x-b.x)*(a.x-b.x)*1.0+(a.y-b.y)*(a.y-b.y)*1.0);
}
int main(){
while(scanf("%d%lf",&n,&d)!=EOF){
if(n==0){
if(d>=42.5)
printf("42.50 1\n");
else printf("can't be saved\n");
continue;
}
for(int i=1;i<=n;i++)
scanf("%lf%lf",&node[i].x,&node[i].y);
node[n+1].x=node[n+1].y=50;
node[0].x=node[0].y=0;
if(d>=42.5){
printf("42.50 1\n");
continue;
}
for(int i=0;i<=n+1;i++)
for(int j=0;j<=n+1;j++)
mp[i][j]=(i==j?0:INF);
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++){
if(i==j)continue;
double len=_len(node[i],node[j]);
if(i==0||j==0)len-=7.5;
if(len<=0)len=0;
if(len<=d)mp[i][j]=len;
}
for(int i=0;i<=n;i++)
{
double c=min(50-node[i].x,50-node[i].y);
c=min(c,min(50+node[i].x,50+node[i].y));
if(c>d) c=INF;
mp[i][n+1]=mp[n+1][i]=c;
}
spfa(0,n+1);
}
return 0;
}