[2016-04-02][POJ][2253][Frogger]

Posted 红洋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[2016-04-02][POJ][2253][Frogger]相关的知识,希望对你有一定的参考价值。

  • 时间:2016-04-02 17:55:33 星期六

  • 题目编号:[2016-04-02][POJ][2253][Frogger]

  • 题目大意:给定n个点的坐标,问从起点到终点的所有路径中,最大边的最小值是多少,即每一步至少是多少才能走到终点

  • 分析:

    • 方法1:
      • 枚举出完全图,然后从起点跑一次Dijkstra算法,不过选点不再是选择起点到终点路径的点,而是起点到终点的路径中,边最大边最小的点,即d数组保存起点到当前点的路径中最大边的最小值,
        • 最大边的最小值:u->v d[v] = min(d[i],max(d[u],g[u][v])) 即通过u -> v的所有路径的,和k -> v(k != u)的所有路径中,最大边取小的那个
    • 方法2:
      • 枚举完全图,跑一次最小生成树,每次合并更新最大边
  • 遇到的问题:

  1. //方法1: Dijkstra
  2. #include <queue>
  3. #include <cstring>
  4. #include <cstdio>
  5. #include <cmath>
  6. using namespace std;
  7. const int maxn = 200 + 10;
  8. struct Point{
  9. int x,y;
  10. }p[maxn];
  11. struct Node{
  12. int v,c;
  13. Node(int _v = 0,int _c = 0):v(_v),c(_c){}
  14. bool operator < (const Node & a)const{
  15. return c > a.c;
  16. }
  17. };
  18. int a[maxn][maxn],d[maxn],vis[maxn],n;
  19. void Dijkstra(int s){
  20. priority_queue< Node > q;
  21. memset(vis,0,sizeof(vis));
  22. memset(d,0x3f,sizeof(d));
  23. d[s] = 0;
  24. q.push(Node(s,0));
  25. Node tmp;
  26. while(!q.empty()){
  27. tmp = q.top();q.pop();
  28. int u = tmp.v;
  29. if(vis[u]) continue;
  30. vis[u] = 1;
  31. for(int i = 1;i <= n ; ++i){
  32. if(i != u && !vis[i]){
  33. d[i] = min(d[i],max(d[u] , a[u][i]));
  34. q.push(Node(i,d[i]));
  35. }
  36. }
  37. }
  38. }
  39. int main(){
  40. int cntcase = 0;
  41. while(~scanf("%d",&n)&&n){
  42. for(int i = 1;i <= n ;++i){
  43. scanf("%d%d",&p[i].x,&p[i].y);
  44. }
  45. for(int i = 1;i <= n ; ++i){
  46. for(int j = 1;j <= n ; ++j){
  47. a[i][j] = (p[i].x - p[j].x)*(p[i].x - p[j].x) + (p[i].y - p[j].y)*(p[i].y - p[j].y);
  48. }
  49. }
  50. Dijkstra(1);
  51. printf("Scenario #%d\n",++cntcase);
  52. printf("Frog Distance = %.3f\n\n",sqrt(double(d[2])));
  53. }
  54. return 0;
  55. }

  1. //方法2:并查集
  2. #include <algorithm>
  3. #include <cstring>
  4. #include <cstdio>
  5. #include <cmath>
  6. using namespace std;
  7. const int maxn = 200 + 10;
  8. const int maxm = maxn * maxn / 2;
  9. int fa[maxn];
  10. struct Point{
  11. int x,y;
  12. }p[maxn];
  13. struct Edge{
  14. int u,v,c;
  15. Edge(int _u = 0,int _v = 0,int _c = 0):u(_u),v(_v),c(_c){}
  16. bool operator < (const Edge & a)const{
  17. return c < a.c;
  18. }
  19. }e[maxm];
  20. void ini(int n){
  21. for(int i = 0;i <= n ; ++i){
  22. fa[i] = i;
  23. }
  24. }
  25. int fnd(int x){
  26. return fa[x] == x?x:fa[x] = fnd(fa[x]);
  27. }
  28. int main(){
  29. int cntcase = 0,n;
  30. while(~scanf("%d",&n)&&n){
  31. for(int i = 1;i <= n ;++i){
  32. scanf("%d%d",&p[i].x,&p[i].y);
  33. }
  34. int cnt = 0;
  35. for(int i = 1;i <= n ; ++i){
  36. for(int j = i + 1;j <= n ; ++j){
  37. e[cnt++] = Edge(i,j,(p[i].x - p[j].x)*(p[i].x - p[j].x) + (p[i].y - p[j].y)*(p[i].y - p[j].y));
  38. }
  39. }
  40. sort(e,e+cnt);
  41. int ans = 0,f1,f2;
  42. ini(n);
  43. for(int i = 0;i < cnt ; ++i){
  44. f1 = fnd(e[i].u);f2 = fnd(e[i].v);
  45. if(f1 != f2){
  46. fa[f1] = f2;
  47. ans = max(ans,e[i].c);
  48. }
  49. if(fnd(1) == fnd(2)) break;
  50. }
  51. printf("Scenario #%d\n",++cntcase);
  52. printf("Frog Distance = %.3f\n\n",sqrt(double(ans)));
  53. }
  54. return 0;
  55. }




以上是关于[2016-04-02][POJ][2253][Frogger]的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2253 Frogger

POJ 2253 Frogger

poj2253 最短路变形

POJ2253(dijkstra堆优化)

POJ2253:Frogger(改造Dijkstra)

POJ2253 Frogger —— 最短路变形