poj2253 Dijkstra

我胡汉三又回来啦hhh 消失了好久,又终于开始算法的漫漫长路了,最近的事情终于告一段落。虽然之后还有final p和完全没有底的面试,但是又可以开始刷oj啦撒花。

这次是好好学了Dijkstra之后再来写的这道题,感觉就是完全套用伪代码啊,但是要在松弛的时候改变成这个情况特有的条件。

先把Dijkstra部分的伪码和注解列在下面,之后我再把ac码贴上来。

for each vertex v in V[G]

d[v]:=infinity; //这个要根据题目数据的大小限制想一个比较大的不会越界的数。

previous[v]:=undefined; //学到了一招,此处可有效追溯路径而不用把每一条路径都存起来(每一个都只要记得自己前面是谁就可以了:虽然在这道题里面并没有体现)

d[s]=0;//起始点的参数设为0: A-A=0,自己到自己的距离等于0

S:=empty set;//此题并没有用到

Q:=set of all vertex;//此题还需一个拥有全部点的array


while Q is not empty

u:=Extract_Min(Q);//在余下的所有顶点中找到d[u](参数)最小的那一个点

if u==the second element//在这道题中,第一个点是起始点,第二个点是终点。

break;

S:=S union {u};

for each edge(u,v) outgoing from u

record=Max(d[u],weight(u,v));//到u为止的最大边长度是d[u],从u到v,要取d[u]与u到v距离的较大值

if(record<d[v])

d[v]=record;//用这个较大值对v进行较小边松弛

previous[v]=u;

#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
using namespace std;
struct Point{
    int x;
    int y;
    int index;
    Point(int X, int Y, int Index){
        x=X;
        y=Y;
        index=Index;
    }
};
int no_case=1;
int num_stone=0;
int INF=20000;
vector<Point> Q;
vector<Point> points;
double d[400];
int previous[400];
double weight(Point u, Point v){
    double dx=u.x-v.x;
    double dy=u.y-v.y;
    
    double d2=pow(dx,2)+pow(dy,2);
    d2=sqrt(d2);
    
    return d2;
}
int Extract_Min(){
    int index=Q[0].index;
    double record=d[Q[0].index];
    for(int i=0;i<Q.size();i++){
        if(d[Q[i].index]<record){
            record=d[Q[i].index];
            index=Q[i].index;
        }
    }
    return index;
}
int main(int argc, const char * argv[]) {
    // insert code here...
    while(cin>>num_stone){
        if(num_stone==0)
            break;
        for(int i=0;i<num_stone;i++){
            int x,y;
            cin>>x>>y;
            Point p(x,y,i);
            Q.push_back(p);
            d[i]=INF;
            previous[i]=-1;
        }
        points=Q;
        d[0]=0;
        while(!Q.empty()){
            int u=Extract_Min();
            if(u==1){
                cout<<"Scenario #"<<no_case++<<endl;
                cout<<"Frog Distance = "<<setiosflags(ios::fixed)<<setprecision(3)<<d[u]<<endl<<endl;
            }
            vector<Point>::iterator it;
            it=Q.begin();
            for(int i=0;i<Q.size();i++,it++){
                if(Q[i].index==u){
                    Q.erase(it);
                }
            }
            for(int v=0;v<num_stone;v++){
                double w=weight(points[u],points[v]);
                double side=(w>d[u])? w:d[u];
                if(side<d[v]){
                    d[v]=side;
                    previous[v]=u;
                }
            }
        }
        points.clear();
        Q.clear();
        
    }
    
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值