Dijkstra 最短路径 优化

 

/********************************************************************
 ** @file    d.cpp
 ** @date    Thu Apr 28 20:53:05 2011
 ** @brief   ******普通Dijstra算法********
 **     以poj 2387 做试验
 ********************************************************************/
#include<iostream>
#include<cstring>
using namespace std;
#define MAX 1001
#define INF 1e9
int t,n;int g[MAX][MAX];
void input(){
  cin>>t>>n;int v1,v2,w;
  for(int i=1;i<=n;++i){
    for(int j=1;j<=n;++j)
      g[i][j]=INF;
  }
  for(int i=0;i<t;++i){
    cin>>v1>>v2>>w;
    if(w<g[v1][v2]){
      g[v1][v2]=w;g[v2][v1]=w;      
    }    
  }
}
int Dijistra(){
  int d[MAX];bool visted[MAX]={false};
  for(int i=1;i<=n;++i)d[i]=(i==1?0:INF);
  for(int i=1;i<=n;++i){
    int x,m=INF;
    for(int y=1;y<=n;++y)if(!visted[y] && m>=d[y])m=d[x=y];
    visted[x]=true;
    for(int y=1;y<=n;++y)
      d[y]=(d[y]<d[x]+g[x][y])?d[y]:(d[x]+g[x][y]);
  }
  return d[n];
}
int main(int argc, char *argv[])
{
  input();
  cout<<Dijistra()<<endl;
  return 0;
}





使用优先队列的Dijsktra算法



/********************************************************************
 ** @file    poj2387.cpp
 ** @date    Thu May 12 16:12:19 2011
 ** @brief   使用了优先队列的Dijsktra算法
 **     
 ********************************************************************/
#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
#define MAX 4003
#define INF 999999
struct node{
  int v,w,next;
}e[MAX];
int p[MAX],t,n;
void input(){
  int index=0;
  int a,b,w;
  //稀疏图的临界表法,当然在c++中可以用向量vector存储稀释图
  scanf("%d%d",&t,&n);
  memset(p,-1,sizeof(p));
  for(int i=0;i<t;++i){
    scanf("%d%d%d",&a,&b,&w);
    a--;b--;//每次都是倒着插入
    e[index].v=b;//a顶点指向b 即:a->b
    e[index].w=w;//a到b这条边的权重
    e[index].next=p[a];//a所连接的另一条边
    p[a]=index++;
    //因为是无向图
    e[index].v=a;
    e[index].w=w;
    e[index].next=p[b];
    p[b]=index++;
  }
}
int min(int a,int b){
  return a>b?b:a;
}
int Dijistra(){
  int d[MAX];
  bool vis[MAX]={false  };
  for(int i=0;i<n;++i)d[i]=(i==0?0:INF);
  typedef pair<int,int>pii;//pair 定义了自己的排序规则--先比较第一维,相等才比较第二维
  priority_queue<pii,vector<pii>,greater<pii> >q;
  q.push(make_pair(d[0],0));
  while(!q.empty()){
    pii u=q.top();q.pop();
    int x=u.second;
    for(int i=p[x];i!=-1;i=e[i].next)
      if(d[e[i].v]>d[x]+e[i].w){
        d[e[i].v]=d[x]+e[i].w;
        q.push(make_pair(d[e[i].v],e[i].v));
      }
  }
  return d[n-1];
}
int main(int argc, char *argv[])
{
  input();
  printf("%d/n",Dijistra());
  return 0;
}





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值