有一片100*100的湖泊,中心坐标(0,0),即湖泊右上角的坐标是(50,50),湖泊中间有一片以(0,0)为圆心,15为直径的圆形陆地。现有一个人在陆地,湖泊中散布着一些点可以踩,这个人要利用这些点跳到岸上,求最短路径和最短路径下的最短步数。
spfa莫名其妙的超时,dij+堆优化反而能过。。。可能spfa更适合有向图吧。
使用vector<vector<node> > g这种双重结构时,最好先g.resize(N)设置一下容量,否则直接插入会出错。
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<cmath> 5 #include<cstdlib> 6 #include<queue> 7 using namespace std; 8 const double inf=1<<30; 9 int n; 10 double limit; 11 struct node 12 { 13 double w; 14 int v; 15 int path; 16 node(double ww,int vv,int ppath):w(ww),v(vv),path(ppath){} 17 node(){} 18 bool operator <(const node &dd) const 19 { 20 if(w!=dd.w) 21 return w>dd.w; 22 else 23 return path>dd.path; 24 } 25 }; 26 vector<vector<node> > g; 27 double dis(double x1,double y1,double x2,double y2) 28 { 29 return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); 30 } 31 double mmax(double aa,double bb) 32 { 33 if(aa>bb) return aa; 34 else return bb; 35 } 36 int vis[110]; 37 38 int main() 39 { 40 double x[110],y[110]; 41 int i,j; 42 while(scanf("%d%lf",&n,&limit)!=EOF) 43 { 44 priority_queue<node> q; 45 g.clear(); 46 g.resize(n+10); 47 for(i=1;i<=n;i++) 48 scanf("%lf%lf",&x[i],&y[i]); 49 for(i=1;i<=n;i++) 50 { 51 double dd=dis(x[i],y[i],0.0,0.0)-7.5; 52 if(dd<=limit) 53 { 54 g[0].push_back(node(dd,i,0)); 55 g[i].push_back(node(dd,0,0)); 56 } 57 } 58 for(i=1;i<=n;i++) 59 { 60 for(j=i+1;j<=n;j++) 61 { 62 double dd=dis(x[i],y[i],x[j],y[j]); 63 if(dd<=limit) 64 { 65 g[i].push_back(node(dd,j,0)); 66 g[j].push_back(node(dd,i,0)); 67 } 68 } 69 } 70 double mm; 71 for(i=1;i<=n;i++) 72 { 73 mm=mmax(fabs(x[i]),fabs(y[i])); 74 if(50-mm<=limit) 75 { 76 g[i].push_back(node(50-mm,n+1,0)); 77 g[n+1].push_back(node(50-mm,i,0)); 78 } 79 } 80 //前面都是建图 81 q.push(node(0,0,0));//放入起点 82 memset(vis,0,sizeof(vis));//标记这个点的最短路是否已经求出 83 node z; 84 bool flag=false;//判断有无解 85 while(!q.empty()) 86 { 87 z=q.top(); 88 q.pop(); 89 if(vis[z.v]) continue;//这个点最短路已经求出,不需要继续求了 90 vis[z.v]=1;//标记这个点的最短路已求出 91 if(z.v==n+1) {flag=true;break;}//因为只需要求起点到n+1的最短路,所以可以结束了 92 for(i=0;i<g[z.v].size();i++) 93 { 94 node zz; 95 zz.v=g[z.v][i].v; 96 if(vis[zz.v]) continue; 97 zz.w=z.w+g[z.v][i].w; 98 zz.path=z.path+1; 99 q.push(zz);//反正是优先队列,不用管队列中是否已经存在zz,更新最短路的时候也不用管是否能使当前的最短路变得更短 100 } 101 } 102 if(flag) 103 printf("%.2f %d\n",z.w,z.path); 104 else printf("can‘t be saved\n"); 105 } 106 return 0; 107 }
时间: 2024-10-11 07:24:43