zoukankan      html  css  js  c++  java
  • 关于最短路算法的学习

    对prim算法和dijk算法搞混了

    归根结底还是对算法的理解不够透彻

    先写一道变型dijk算法

    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

    明显的最短路算法

    对于dijk说一下原理

    对于一个图将其分为v e

    v表示已经确定由起点到达该店的最短最短路

    e表示还未确定

    首先将起点放入

    先写一个普通最短路

    再写一个堆优化的最短路(此题也能堆优化)

    于prim算法不同的是prim算法算法更新的dis是当前的最小边的长度

    关于dijk为什么无法处理负环的问题

    https://blog.csdn.net/blink_invoker/article/details/27181285

    简单粗暴的最短路算法

    bellman ford

    https://www.cnblogs.com/lxt1105/p/6477639.html

    可解决负权边问题 同样是否可以判定负权环

    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<string>
    #include<iostream>
    #include<list>
    #include<stack>
    #include<deque>
    #include<cstring>
    #include<cmath>
    using namespace std;
    pair<double,double> a[1005];
    double dis[1005];
    int vis[1005];
    inline double  distant(int x,int y)
    {
        return sqrt((a[x].first-a[y].first)*(a[x].first-a[y].first)+(a[x].second-a[y].second)*(a[x].second-a[y].second));
    }
    int main()
    {
        int n;
        int cas=0;
        double temp1,temp2;
        while(~scanf("%d",&n))
        {
            cas++;
            if(n==0) break;
            memset(vis,0,sizeof(vis));
            memset(dis,-1,sizeof(dis));
            for(int i=1; i<=n; i++)
            {
                scanf("%lf%lf",&temp1,&temp2);
                a[i]=make_pair(temp1,temp2);
            }
            double MIN;
            int k;
            for(int i=1;i<=1000;i++) dis[i]=1e9+1;
            dis[1]=0;
            for(int i=1; i<n; i++)
            {
                MIN=1e9;
                for(int j=1; j<=n; j++)
                {
                    if(vis[j]==0&&MIN>dis[j])
                    {
                        MIN=dis[j];
                        k=j;
                    }
                }//选择当前由v中到e的最近的点 由贪心保证正确性
                if(vis[k]==1) break;
                vis[k]=1;//将该点加入到集合v
           
                for(int j=1; j<=n; j++)
                {
                    if(dis[j]>max(dis[k],distant(k,j)))
                    {
                        dis[j]=max(dis[k],distant(k,j));
                    }
                }//用最新加入v的点来松弛到所有点的距离
            }
            printf("Scenario #%d
    ",cas);
            printf("Frog Distance = %.3lf
    
    ",dis[2]);
    
        }
    }
    
    ​
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<string>
    #include<iostream>
    #include<list>
    #include<stack>
    #include<deque>
    #include<cstring>
    using namespace std;
    struct node
    {
        int to;
        int w;
        int nex;
        bool operator > (const node temp) const
        {
            return w>temp.w;
        }
    }a[10005];
    int first[10005];
    int dis[10005];
    int vis[10005];
    priority_queue< node, vector<node> ,greater<node> > q;
    int main()
    {
        //freopen("in.txt","r",stdin);
        int tmp1,tmp2,tmp3;
        memset(a,-1,sizeof(0));
        memset(first,-1,sizeof(first));
        memset(vis,-1,sizeof(vis));
        memset(dis,0x3f,sizeof(dis));
        int t,n;
        scanf("%d%d",&t,&n);
        int cnt=1;
        for(int i=1;i<=t;i++)
        {
    //链式前向星存图first代表当前权值 second代表目标点
            scanf("%d%d%d",&tmp1,&tmp2,&tmp3);
            a[cnt].nex=first[tmp1];
            a[cnt].to=tmp2;
            a[cnt].w=tmp3;
            first[tmp1]=cnt;
            cnt++;
            a[cnt].nex=first[tmp2];
            a[cnt].to=tmp1;
            a[cnt].w=tmp3;
            first[tmp2]=cnt;
            cnt++;
        }
        dis[1]=0;
        node temp;
        temp.to=1;
        temp.w=0;
        temp.nex=0;
        q.push(temp);//将起点加入到v中
        while(q.size())
        {
            node temp2;
            temp=q.top();
            q.pop();
            if(vis[temp.to]==1) continue;
            vis[temp.to]=1;//将堆顶元素加入到集合v中
            for(int i=first[temp.to];i!=-1;i=a[i].nex)
            {
                if(dis[a[i].to]>dis[temp.to]+a[i].w)
                {//若满足松弛条条件将该点松弛并将松弛后的点的新距离加入到堆中
                    dis[a[i].to]=dis[temp.to]+a[i].w;
                    temp2.w=dis[a[i].to];
                    temp2.to=a[i].to;
                    q.push(temp2);
                }
            }
           // cout<<endl;
        }
        printf("%d
    ",dis[n]);
    }
    
    ​

    对于堆优化的dijk的算法 我们只需要把每一个松弛过的边 加入到堆中 最后将堆遍历完即可

  • 相关阅读:
    sql server 中将由逗号“,”分割的一个字符串,转换为一个表,并应用于 in 条件,方法和调用
    JavaScript Invalid Date Verify
    Jquery总结
    java中的异常和处理
    联系 管理 Hibernate4+Spring JPA+SpringMVC+Volecity搭建web应用(三)
    Hibernate4+Spring JPA+SpringMVC+Volecity搭建web应用(二)
    Hibernate4+Spring JPA+SpringMVC+Volecity搭建web应用(一)
    Spring 框架整理
    java 三大框架 介绍
    struts2 拦截器的注册在strut.xml中
  • 原文地址:https://www.cnblogs.com/caowenbo/p/11852319.html
Copyright © 2011-2022 走看看