传送门http://acm.hdu.edu.cn/showproblem.php?pid=2544

思路:最短路的模板题

Dijkstra 算法是一种类似于贪心的算法,步骤如下:

1、当到一个点时,图上部分的点的最短距离已确定,部分点的最短距离未确定。

2、选一个所有未确定点中离源点最近的点,把它认为成最短距离。

3、再把这个点所有出边遍历一边,更新所有的点。

朴素算法(适用于稠密图 复杂度

#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 105;
const int INF = 9999999;
int w[maxn][maxn];
int dis[maxn];
bool vis[maxn];
int n, m;
void dijkstra()
{
for(int i = 1; i <= n; i++)
vis[i] = false;
for(int i = 1; i <= n; i++)
dis[i] = (i == 1 ? 0 : INF);
for(int i = 1; i <= n; i++)
{
int x, m = INF;
for(int y = 1; y <= n; y++)
{
if(!vis[y] && dis[y] <= m)
m = dis[x = y];
}
vis[x] = true;
for(int y = 1; y <= n; y++)
{
dis[y] = min(dis[y], dis[x] + w[x][y]);
}
}
}
int main()
{
while(scanf("%d%d", &n, &m) != EOF)
{
if(n == m && n == 0)
break;
else
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
w[i][j] = INF;
for(int i = 1; i <= m; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
w[a][b] = c;
w[b][a] = c;
}
}
dijkstra();
cout << dis[n] << endl;
}
}

优先队列优化(适用于稀疏图 复杂度E*log(V))

#include<iostream>
#include<queue>
using namespace std;
const int maxn = 2e5 + 10;
const int INF = 0x3f3f3f3f;
struct heapnode
{
int d;
int u;
//结构体内嵌函数,速度较快
bool operator <(const heapnode &a) const
{
return d > a.d;
}
};
struct node
{
int to;
int cost;
int next;
};
node edges[maxn << 1];
int head[maxn];
int d[maxn];
bool vis[maxn];
int n, m;
int tot;
void add_edges(int u, int v, int cost)
{
edges[++tot].to = v;
edges[tot].cost = cost;
edges[tot].next = head[u];
head[u] = tot;
}
void dijkstra()
{
priority_queue<heapnode>q;
for(int i = 1; i <= n; i++)
d[i] = INF, vis[i] = 0;
d[1] = 0;
q.push((heapnode)
{
0, 1
});
while(!q.empty())
{
heapnode x = q.top();// 每次取出d值最小的点
q.pop();
int u = x.u;
if(vis[u])
continue;
vis[u] = 1;
for(int i = head[u]; i; i = edges[i].next)
{
node v = edges[i];
if(d[v.to] > d[u] + v.cost)
{
d[v.to] = d[u] + v.cost;
q.push((heapnode)
{
d[v.to], v.to
});
}
}
}
} int main()
{
while(scanf("%d %d", &n, &m) != EOF)
{
if(n == m && n == 0)
break;
else
{
tot = 0;
for(int i = 1; i <= n; i++)
head[i] = 0;
for(int i = 1; i <= m; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add_edges(a, b, c);
add_edges(b, a, c);
}
dijkstra();
cout << d[n] << endl;
}
}
}

最新文章

  1. c#面向对象基础技能——学习笔记(五)委托技术在开发中的应用
  2. Android 网络框架之Retrofit2使用详解及从源码中解析原理
  3. C# 构造post参数一种看起来直观点的方法[转]
  4. iOS webView与H5的交互(返回页面的处理)
  5. SQL Server的各种聚合函数
  6. Linux Shell编程基础
  7. IE6文字溢出BUG(多出来的猪问题)
  8. 30款jQuery常用网页焦点图banner图片切换 下载
  9. Android内存、性能是程序永恒的话题
  10. pyqt5表格qtablewidget
  11. NOI2013 Day2
  12. 如何:打开 IIS 管理器
  13. HDOJ 3415 Max Sum of Max-K-sub-sequence(单调队列)
  14. leetcode第25题--Remove Element
  15. PAT乙级--1003
  16. JVM 学习(二)Java 内存模型、方法内联、逃逸 --- 2019年4月
  17. Java多线程处理某个线程超时的问题
  18. #const#const int *p 为何可以不初始化
  19. Spring及Spring Boot 国内快速开发框架
  20. XMPP接受发送消息

热门文章

  1. Node.js 加载静态资源css,js等不显示问题的解决方法
  2. 7.Python列表
  3. 前端安全之 XSS攻击
  4. Node.js 介绍
  5. Elasticsearch 使用集群 - 删除索引
  6. IT日常技能:VMware网络配置
  7. python---函数作用域
  8. POJ 3461:Oulipo
  9. 【redis】redis底层数据结构原理--简单动态字符串 链表 字典 跳跃表 整数集合 压缩列表等
  10. zoj 2314Reactor Cooling