【图】单源最短路径dijkstra

O(n^2)级C算法,简易复习用

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<cstdlib>
using namespace std;
const int INF = 1000000000;
const int MAXN = 1000;

int n, m;
int v[MAXN], d[MAXN], G[MAXN][MAXN];

int main() {
  scanf("%d%d", &n, &m);
  for(int i = 0; i < n; i++)
    for(int j = 0; j < n; j++)
      G[i][j] = INF;
  for(int i = 0; i < m; i++) {
    int u, v, w;
    scanf("%d%d%d", &u, &v, &w);
    G[u][v] = w;
  }
  
  memset(v, 0, sizeof(v));
  for(int i = 0; i < n; i++) d[i] = (i==0 ? 0 : INF); 
  for(int i = 0; i < n; i++) {
    int x, m = INF;
    for(int y = 0; y < n; y++) if(!v[y] && d[y]<=m) m = d[x=y]; //选出所有未被遍历的点中d值最小的节点x,即到始点最短的点 
    v[x] = 1;//标记点x 
    for(int y = 0; y < n; y++) d[y] = min(d[y], d[x] + G[x][y]);//更新 
  }
  
  for(int i = 0; i < n; i++)
    printf("d[%d] =  %d\n", i, d[i]);
  return 0;
}


C++优先队列优化版

struct Edge
{
  int from,to,dist
}


struct HeapNode
{
  int d,u;//d是距离,u是节点号
  bool operator < (const HeapNode& rhs) const
  {
    return d>rhs.d;
  }
};

struct Dijkstra
{
  int n,m;//vertices and edges
  vector<Edge> edges;
  vector<int> G[maxn];
  bool done[maxn];
  int d[maxn];
  int p[maxn];
  
  void init(int n)
  {
    this->n=n;
    for(int i=0;i<n;i++) G[i].clear();
    edges.clear();
  }
  
  void AddEdge(int from,int to,int dist)
  {
    edges.push_back((Edge){from,to,dist});
    m=edges.size();
    G[from].push_back(m-1);
  }
  
  void dijkstra(int s)
  {
    priority_queue<HeapNode> Q;//有限队列优化
    for(int i=0;i<n;i++) d[i]=INF;//初始化
    d[s]=0;
    memset(done,0,sizeof(done));
	
    Q.push((HeapNode){0,s});//把节点压栈开始
    while(!Q.empty())//当队列非空
    {
	  HeapNode x=Q.top();//队首元素
	  Q.pop();//弹出
	  int u=x.u; 
	  if(done[u]) continue;
	  
	  done[u]=true;
	  for(i=0;i<G[u].size();i++)//遍历所有的边
	  {
	    Edge& e=edges[G[u][i]];
	    if(d[e.to]>d[u]+e.dist)
	    {
		  d[e.to]=d[u]+e.dist;
		  p[e.to]=G[u][i];
		  Q.push((HeapNode){d[e.to],e.to});
		}
	  }
	}
  }
}

汝佳的代码

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
//terraria
const int INF = 1000000000;
const int MAXN = 1000;
const int MAXM = 100000;

int n, m;
int first[MAXN], d[MAXN];
int u[MAXM], v[MAXM], w[MAXM], next[MAXM];

typedef pair<int,int> pii;

int main(void)
{//读入及初始化 
  scanf("%d%d", &n, &m);
  for(int i = 0; i < n; i++) first[i] = -1;
  for(int e = 0; e < m; e++) {
    scanf("%d%d%d", &u[e], &v[e], &w[e]);
    next[e] = first[u[e]];
    first[u[e]] = e;
  }

  priority_queue<pii, vector<pii>, greater<pii> > q;//优先队列 
  //bool done[MAXN];
  for(int i = 0; i < n; i++) d[i] = (i==0 ? 0 : INF);//将所有非0值置为最大 
  //memset(done, 0, sizeof(done));
  q.push(make_pair(d[0], 0));
  while(!q.empty()) {
    pii u = q.top(); q.pop();
    int x = u.second;
    if(x==3) printf("3 occurs, u.first=%d, d[3]=%d\n", u.first, d[3]); 
    if(u.first != d[x]) {printf("node #%d: first=%d, d[x]=%d, continue\n", x,u.first,d[x]); continue;}
    //done[x] = true;
    if(x==3) printf("3 using, d[3] = %d\n", d[3]); 
    for(int e = first[x]; e != -1; e = next[e]) if(d[v[e]] > d[x]+w[e]) {

      d[v[e]] = d[x] + w[e];
      q.push(make_pair(d[v[e]], v[e]));
      printf("%d kuozhanle %d, d=%d\n",x, v[e], d[v[e]]);
    }
  }

  for(int i = 0; i < n; i++)
    printf("d[%d] = %d\n", i, d[i]);
  while(1); 
  return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值