poj2253 Frogger(用单源最短路dijkstra的思路求解)
来源:互联网 发布:阿里云如何备份 编辑:程序博客网 时间:2024/06/05 14:30
题意:在平面坐标的第一象限给出n(2<=n<=200)个点的坐标,一只青蛙要从起点出发跳到终点(途中可以经过任意点),青蛙的落脚点只能在给出的n个点中,问青蛙的跳跃能力最少是多长?
分析过程和dijkstra的过程几乎一摸一样,设d[i]表示从起点到i的所需最短距离,w[i][j]表示点i和j的欧拉距离。
步骤:
1. 设点i未访问,用所有访问的点j更新d[i],更新公式为d[i]=min(d[i],max(d[j],w[i][j]))。
2. 在所有未访问的点i中找出最小的d,然后将该点设为访问。
复杂度O(n^3)的代码:
#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>using namespace std;const double inf=1e9;const int maxn=200;typedef pair<double,double> PAIR;PAIR p[maxn+5];int n;double d[maxn+5];double w[maxn+5][maxn+5];double dis(PAIR &a,PAIR &b){ return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));}bool vis[maxn+5];int find(){ int mini=-1; double mind=inf; for(int i=1;i<=n;i++)if(vis[i]==false){ for(int j=1;j<=n;j++)if(vis[j]){ d[i]=min(d[i],max(d[j],w[i][j])); } if(d[i]<mind){ mind=d[i]; mini=i; } } return mini;}void dj(int cur){ memset(vis,false,sizeof(vis)); fill(d+1,d+1+n,inf),d[cur]=0; while((cur=find())!=-1){ vis[cur]=true; }}int main(){ int T=0; while(scanf("%d",&n),n){ for(int i=1;i<=n;i++){ scanf("%lf%lf",&p[i].first,&p[i].second); for(int j=1;j<=i;j++){ w[i][j]=w[j][i]=dis(p[i],p[j]); } } dj(1);//求出所有点到起点的最小跳跃能力 printf("Scenario #%d\n",++T); printf("Frog Distance = %.3f\n\n",d[2]); }}
可以用优先队列优化到O(n^2logn):
- 设点i未访问,点j已访问,对所有的点j,将max(d[j],w[i][j]) 放到到pq[i]中,每次取出最小的去更新d[i]即可。
- find中更新完d,并且找到最小的d之后,要用它的下标mini去更新所有未访问的点i的pq,更新方程为:pq[i].push(max(d[mini],w[mini][i]))。
#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<queue>using namespace std;const double inf=1e9;const int maxn=200;typedef pair<double,double> PAIR;PAIR p[maxn+5];int n;double d[maxn+5];double w[maxn+5][maxn+5];double dis(PAIR &a,PAIR &b){ return sqrt((a.first-b.first)*(a.first-b.first)+(a.second-b.second)*(a.second-b.second));}priority_queue<double,vector<double>,greater<double> >pq[maxn+5];bool vis[maxn+5];int find(){ int mini=-1; double mind=inf; for(int i=1;i<=n;i++)if(vis[i]==false){ d[i]=min(d[i],pq[i].top()); if(d[i]<mind){ mind=d[i]; mini=i; } } return mini;}void update(int cur){ for(int i=1;i<=n;i++)if(vis[i]==false){ pq[i].push(max(d[cur],w[cur][i])); }}void initpq(){ for(int i=1;i<=n;i++){ while(!pq[i].empty())pq[i].pop(); for(int j=1;j<=n;j++){ pq[i].push(max(d[j],w[i][j])); } }}void dj(int cur){ memset(vis,false,sizeof(vis)); fill(d+1,d+1+n,inf),d[cur]=0; initpq(); while((cur=find())!=-1){ vis[cur]=true; //这里不需要加pq[cur].pop(),因为cur标记为访问之后,find中的i不会是cur了 update(cur); }}int main(){ int T=0; while(scanf("%d",&n),n){ for(int i=1;i<=n;i++){ scanf("%lf%lf",&p[i].first,&p[i].second); for(int j=1;j<=i;j++){ w[i][j]=w[j][i]=dis(p[i],p[j]); } } dj(1); printf("Scenario #%d\n",++T); printf("Frog Distance = %.3f\n\n",d[2]); }}
0 0
- poj2253 Frogger(用单源最短路dijkstra的思路求解)
- POJ2253 Frogger -DIJKSTRA || FLOYD最短路练习
- POJ2253-Frogger(Dijkstra变式)
- POJ2253 Frogger 【Dijkstra】
- POJ2253 Frogger Dijkstra & Floyd
- POJ2253 Frogger(最短路变形,floyd,Dijkstra,spfa)
- poj2253 Frogger +poj1797Heavy Transpotaion(最短路dijkstra变式)
- poj2253 - Frogger(最短路变形)
- poj2253~Frogger(最短路floyd)
- POJ2253---Frogger(最短路变形)
- poj2253—Frogger (并查集最短路)
- ZOJ1942 POJ2253 Frogger,Dijkstra算法
- poj2253 Frogger(最短路变形)
- POJ2253 Frogger 最短路变形
- POJ 2253 - Frogger(最短路`dijkstra)
- poj 2253 Frogger (dijkstra最短路)
- POJ2253&ZOJ1942--Frogger【SPFA】单源最短路变形
- POJ2253 Frogger(floyd最短路算法)
- 17. Letter Combinations of a Phone Number
- Office编程 VS操作Office文档
- 自定义生成DBML文件
- 跟着我左手右手一个慢动作,轻松提交AppStore(AppStore提交App流程最新超详细攻略)(填表篇)
- HTTP协议详解(真的很经典)
- poj2253 Frogger(用单源最短路dijkstra的思路求解)
- 最短路径问题/Spfa
- Struts类型转换实现
- php中和mysql数据库相关函数
- 数据库三范式简介
- 关于链接地址为JavaScript:void(0)的问题
- 洛谷 P2530 [SHOI2001] 化工厂装箱员
- 划分树(求区间第k小值)
- tomcat在win7下不能连接的解决方案