对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\n",cas);
        printf("Frog Distance = %.3lf\n\n",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\n",dis[n]);
}

​

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