zoukankan      html  css  js  c++  java
  • POJ 2253 Frogger (最短路)

    Frogger
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 28333   Accepted: 9208

    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' sunscreen, he wants to avoid swimming and instead reach her by jumping. 
    Unfortunately Fiona's stone is out of his jump range. Therefore Freddy considers to use other stones as intermediate stops and reach her by a sequence of several small jumps. 
    To execute a given sequence of jumps, a frog's jump range obviously must be at least as long as the longest jump occuring in the sequence. 
    The frog distance (humans also call it minimax distance) between two stones therefore is defined as the minimum necessary jump range over all possible paths between the two stones. 

    You are given the coordinates of Freddy's stone, Fiona's stone and all other stones in the lake. Your job is to compute the frog distance between Freddy's and Fiona's stone. 

    Input

    The input will contain one or more test cases. The first line of each test case will contain the number of stones n (2<=n<=200). The next n lines each contain two integers xi,yi (0 <= xi,yi <= 1000) representing the coordinates of stone #i. Stone #1 is Freddy's stone, stone #2 is Fiona's stone, the other n-2 stones are unoccupied. There's a blank line following each test case. Input is terminated by a value of zero (0) for n.

    Output

    For each test case, print a line saying "Scenario #x" and a line saying "Frog Distance = y" where x is replaced by the test case number (they are numbered from 1) and y is replaced by the appropriate real number, printed to three decimals. Put a blank line after each test case, even after the last one.

    Sample Input

    2
    0 0
    3 4
    
    3
    17 4
    19 4
    18 5
    
    0
    

    Sample Output

    Scenario #1
    Frog Distance = 5.000
    
    Scenario #2
    Frog Distance = 1.414





    刚开始不会做,看了网上的提示的后说是这是Dijkstra的变种,然后还风轻云淡的说更新条件变一下就行了,结果这句话坑大了,严格来说这就不是Dijkstra!
    Dijkstra维护的是两个集合,加入到S集合之中的点已经确定正确,无需再计算,但是这题不一样,就因为这点WA了十多发。关于原算法中S里的点已经正确的证明移步我前一篇博文,但是对于这题用,同样的证明方法,得不出S里的点已经正确的结论。
    首先假设S中的点已经最优,而且假设即将加入S的点u没有最优,那么存在一条路径 S里的点 + 任意一点 -> u 是最优的。
    那么,如果此任意点属于S,因为维护小顶堆,所以下一个确实应该讲u加入,此处无矛盾。
    然后,如果此任意点不属于S,那么就存在两种情况,要么D[s]>D[u],要么D[s]<D[u],但是两种情况都可以成立,也即是说这条假设的路径是可以存在的!
    所以,将算法里对S的集合维护取消就对了,只是这还算迪杰斯特拉么?稍后补上另外几种算法的代码。
     1 #include <iostream>
     2 #include <cmath>
     3 #include <cstdio>
     4 #include <vector>
     5 #include <queue>
     6 using    namespace    std;
     7 
     8 const    int    SIZE = 205;
     9 const    int    INF = 0x6fffffff;
    10 int    N;
    11 int    TEMP[SIZE][2];
    12 double    D[SIZE];
    13 bool    S[SIZE];
    14 struct    Comp
    15 {
    16     bool    operator ()(int & a,int & b)
    17     {
    18         return    D[a] > D[b];
    19     }
    20 };
    21 struct    Node
    22 {
    23     int    vec;
    24     double    cost;
    25 };
    26 vector<Node>    G[SIZE];
    27 
    28 double    dis(int x_1,int y_1,int x_2,int y_2);
    29 void    dijkstra(int);
    30 int    main(void)
    31 {
    32     int    count = 0;
    33     Node    temp;
    34 
    35     while(scanf("%d",&N) && N)
    36     {
    37         for(int i = 1;i <= N;i ++)
    38             scanf("%d%d",&TEMP[i][0],&TEMP[i][1]);
    39         for(int i = 1;i <= N;i ++)
    40             G[i].clear();
    41         for(int i = 1;i <= N;i ++)
    42             for(int j = i + 1;j <= N;j ++)
    43             {
    44                 temp.vec = j;
    45                 temp.cost = dis(TEMP[i][0],TEMP[i][1],TEMP[j][0],TEMP[j][1]);
    46                 G[i].push_back(temp);
    47                 temp.vec = i;
    48                 G[j].push_back(temp);
    49             }
    50 
    51         dijkstra(1);
    52         printf("Scenario #%d
    ",++ count);
    53         printf("Frog Distance = %.3f
    ",D[2]);
    54         puts("");
    55     }
    56 
    57     return    0;
    58 }
    59 
    60 double    dis(int x_1,int y_1,int x_2,int y_2)
    61 {
    62     return    sqrt(pow((double)x_1 - x_2,2) + pow((double)y_1 - y_2,2));
    63 }
    64 
    65 void    dijkstra(int s)
    66 {
    67     fill(D,D + SIZE,INF);
    68     fill(S,S + SIZE,false);
    69     D[s] = 0;
    70     priority_queue<int,vector<int>,Comp>    que;
    71     que.push(s);
    72 
    73     while(!que.empty())
    74     {
    75         int    cur = que.top();
    76         que.pop();
    77         if(cur == 2)
    78             break;
    79         /*S[cur] = true;    注释部分即为原Dij应有的部分,此题要移除,加上即WA*/
    80 
    81         for(int i = 0;i < G[cur].size();i ++)
    82             if(/*!S[G[cur][i].vec] && */D[G[cur][i].vec] > max(G[cur][i].cost,D[cur]))
    83             {
    84                 D[G[cur][i].vec] = max(G[cur][i].cost,D[cur]);
    85                 que.push(G[cur][i].vec);
    86             }
    87     }
    88 }
    #include <iostream>
    #include <queue>
    #include <cstdio>
    #include <cmath>
    using    namespace    std;
    
    const    int    INF = 0x6fffffff;
    const    int    SIZE = 205;
    int    N;
    double    D[SIZE];
    struct    Node
    {
        int    vec;
        double    cost;
    };
    struct    
    {
        int    x,y;
    }TEMP[SIZE];
    vector<Node>    G[SIZE];
    
    double    dis(int,int,int,int);
    void    SPFA(int);
    int    main(void)
    {
        Node    temp;
        int    count = 0;
    
        while(scanf("%d",&N) && N)
        {
            for(int i = 1;i <= N;i ++)
                scanf("%d%d",&TEMP[i].x,&TEMP[i].y);
            for(int i = 1;i <= N;i ++)
                G[i].clear();
            for(int i = 1;i <= N;i ++)
                for(int j = i + 1;j <= N;j ++)
                {
                    temp.vec = j;
                    temp.cost = dis(TEMP[i].x,TEMP[i].y,TEMP[j].x,TEMP[j].y);
                    G[i].push_back(temp);
                    temp.vec = i;
                           G[j].push_back(temp);    
                }
            SPFA(1);
            printf("Scenario #%d
    ",++ count);
            printf("Frog Distance = %.3f
    ",sqrt(D[2]));
            puts("");
        }
    
        return    0;
    }
    
    double    dis(int x_1,int y_1,int x_2,int y_2)
    {
        return    pow((double)x_1 - x_2,2) + pow((double)y_1 - y_2,2);
    }
    
    void    SPFA(int s)
    {
        queue<int>    que;
        fill(D,D + SIZE,INF);
        D[s] = 0;
        que.push(s);
    
        while(!que.empty())
        {
            int    cur = que.front();
            que.pop();
    
            for(int i = 0;i < G[cur].size();i ++)
                if(D[G[cur][i].vec] > max(D[cur],G[cur][i].cost))
                {
                    D[G[cur][i].vec] = max(D[cur],G[cur][i].cost);
                    que.push(G[cur][i].vec);
                }
        }
    }
  • 相关阅读:
    基于Tire树和最大概率法的中文分词功能的Java实现
    通过 Spring RestTemplate 调用带请求体的 Delete 方法(Delete With Request Body)
    《高效能程序员的修炼》之译者序(本书将于7月初上市,人民邮电出版社)
    JVM类加载过程学习总结
    Web安全之Cookie劫持
    2016第40周五
    年轻By塞缪尔·厄尔曼
    2016第40周三
    2016第40周二
    果断歌
  • 原文地址:https://www.cnblogs.com/xz816111/p/4504297.html
Copyright © 2011-2022 走看看