[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. }

来自为知笔记(Wiz)

时间: 2024-12-25 01:09:47

[2016-04-02][POJ][2253][Frogger]的相关文章

POJ 2253 Frogger

题意:一只青蛙找到另外一只青蛙,不过可以通过其它的石头跳到目标青蛙的位置去,其中,输入数据的时候第一组数据是第一只青蛙的位置,第二组是目标青蛙的位置,其它的为石头的位置 思路:dijkstra算法的一种小小的变形,做法还是一样的 Tips:POJ上的双精度浮点型输出竟然是%f输出害的我一直错,或者是编译错误,恼啊! AC代码: #include<cstdio> #include<cmath> #include<algorithm> using namespace std

Floyd-Warshall算法(求解任意两点间的最短路) 详解 + 变形 之 poj 2253 Frogger

/* 好久没有做有关图论的题了,复习一下. --------------------------------------------------------- 任意两点间的最短路(Floyd-Warshall算法) 动态规划: dp[k][i][j] := 节点i可以通过编号1,2...k的节点到达j节点的最短路径. 使用1,2...k的节点,可以分为以下两种情况来讨论: (1)i到j的最短路正好经过节点k一次 dp[k-1][i][k] + dp[k-1][k][j] (2)i到j的最短路完全

poj 2253 Frogger 解题报告

题目链接:http://poj.org/problem?id=2253 题目意思:找出从Freddy's stone  到  Fiona's stone  最短路中的最长路. 很拗口是吧,举个例子.对于 i 到 j 的一条路径,如果有一个点k, i 到 k 的距离 && k 到 j 的距离都小于 i 到 j 的距离,那么就用这两条中较大的一条来更新 i 到 j 的距离 .每两点之间都这样求出路径.最后输出 1 到 2 的距离(1:Freddy's stone   2:Fiona's sto

poj 2253 Frogger (最长路中的最短路)

链接:poj 2253 题意:给出青蛙A,B和若干石头的坐标,现青蛙A想到青蛙B那,A可通过任意石头到达B, 问从A到B多条路径中的最长边中的最短距离 分析:这题是最短路的变形,以前求的是路径总长的最小值,而此题是通路中最长边的最小值,每条边的权值可以通过坐标算出,因为是单源起点,直接用SPFA算法或dijkstra算法就可以了 SPFA 16MS #include<cstdio> #include<queue> #include<cmath> #include<

poj 2253 Frogger (dijkstra最短路)

题目链接:http://poj.org/problem?id=2253 Frogger Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 25773   Accepted: 8374 Description Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on an

POJ 2253 - Frogger (floyd)

A - Frogger Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to

poj 2253 Frogger [dijkstra]

传送门:http://poj.org/problem?id=2253 Frogger Description Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to visit her, but since the water is dirty and full of tourists

POJ - 2253 Frogger(Floyd最短路+预处理)

题目链接:http://poj.org/problem?id=2253 题意:青蛙要从点1到点2,给出各点的坐标,如果点A到点B可以通过A->C,C->B,A到B的距离可以用A->C和C-B中较长的一边代替(如果A直接到B更短的话就不用了),求点1到点2的最短距离. 题解:本来想用dijkst,但是想想就200的数据量,直接Floyd岂不美滋滋.先预处理一下各点之间的距离.因为取两条边中较长的那条边,所以转移的话,那转移的两条边都要比原来的短才可以. 值得注意的是用C的格式输入的时候要用

POJ 2253 Frogger(Dijkstra变形——最短路径最小权值)

题目链接: http://poj.org/problem?id=2253 Description Freddy Frog is sitting on a stone in the middle of a lake. Suddenly he notices Fiona Frog who is sitting on another stone. He plans to visit her, but since the water is dirty and full of tourists' suns