单源最短路径算法之dijstra

//dijstra算法(邻接矩阵)
//以poj 2387为例
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int N = 1001;
int graph[N][N];
int dist[N];
//int pre[N];
bool visit[N];
int n, m;

//void dijstra( int v0, int v1 )
void dijstra( int v0 )
{
  for ( int i = 1; i <= n; i++ )
  {
    dist[i] = graph[v0][i];
    /*
    if ( dist[i] == -1 )
    {
      pre[i] = -1;
    }
    else
    {
      pre[i] = v0;
    }
    */
  }
  //pre[v0] = 0;
  dist[v0] = 0;
  visit[v0] = 1;
  for ( int i = 1; i < n; i++ )
  {
    int mindist = -1;
    int u = v0;
    for ( int j = 1; j <= n; j++ )
    {
      if ( visit[j] || dist[j] == -1 )
      {
        continue;
      }
      if ( mindist == -1 || dist[j] < mindist )
      {
        mindist = dist[j];
        u = j;
      }
    }
    if ( u == v0 )
    {
      return ;
    }
    visit[u] = 1;
    //if ( u == v1 )
    //{
    //  return ;
    //}
    for ( int j = 1; j <= n; j++ )
    {
      if ( visit[j] || graph[u][j] == -1 )
      {
        continue;
      }
      if ( dist[j] == -1 || dist[j] > dist[u] + graph[u][j] )
      {
        dist[j] = dist[u] + graph[u][j];
        //pre[j] = u;
      }
    }
  }
}

int main ()
{
  while ( scanf("%d%d", &m, &n) != EOF )
  {
    memset( visit, 0, sizeof(visit) );
    memset( graph, -1, sizeof(graph) );
    int a, b, c;
    while ( m-- )
    {
      scanf("%d%d%d", &a, &b, &c);
      if ( graph[a][b] == -1 || c < graph[a][b] )
      {
        graph[a][b] = graph[b][a] = c;
      }
    }
    //1到n的最短路
    dijstra(1);
    printf("%d\n", dist[n]);
  }
  return 0;

}


/*

//优先队列优化的dijstra算法(邻接表):

//还是poj 2387

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;

const int N = 1001;
const int M = N * 3;
int head[N];
int dist[N];
bool visit[N];
int n, m, e;

inline void init()
{
  e = 0;
  memset( head, -1, sizeof(head) );
  memset( dist, -1, sizeof(dist) );
  memset( visit, 0, sizeof(visit) );
}

struct Edge
{
  int v;
  int d;
  int next;
} edge[M];

void addEdge( int u, int v, int d )
{
  edge[e].v = v;
  edge[e].d = d;
  edge[e].next = head[u];
  head[u] = e++;
}

struct V
{
  int id;
  int val;
  friend bool operator < ( const V & a, const V & b )
  {
    return a.val > b.val;
  }
};

//void dijstra( int v0, int v1 )
void dijstra( int v0 )
{
  priority_queue<V> q;
  dist[v0] = 0;
  V t;
  t.id = v0;
  t.val = 0;
  q.push(t);
  for ( int i = 1; i <= n; i++ )
  {
    while (1)
    {
      if ( q.empty() )
      {
        return ;
      }
      t = q.top();
      q.pop();
      if ( !visit[t.id] )
      {
        break;
      }
    }
    visit[t.id] = 1;
    //if ( t.id == v1 )
    //  return ;
    int u = t.id;
    for ( int j = head[u]; j != -1; j = edge[j].next )
    {
      int v = edge[j].v;
      if ( visit[v] )
      {
        continue;
      }
      if ( dist[v] == -1 || dist[v] > dist[u] + edge[j].d )
      {
        dist[v] = dist[u] + edge[j].d;
        t.id = v;
        t.val = dist[v];
        q.push(t);
      }
    }
  }
}

int main ()
{
  while ( scanf("%d%d", &m, &n) != EOF )
  {
    init();
    int a, b, c;
    while ( m-- )
    {
      scanf("%d%d%d", &a, &b, &c);
      addEdge( a, b, c );
      addEdge( b, a, c );
    }
    dijstra(n);
    printf("%d\n", dist[1]);
  }
  return 0;
}



*/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值