传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2544
链式前向星储存的优先队列优化dijkstra. 模板.
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int MAXN = 111, MAXE = 1e4+10;
struct Edge {
int to, nxt, w;
}edge[MAXE << 1];
int head[MAXN], ecnt;
void addedge(int pre, int to, int w) {
edge[ecnt].nxt = head[pre];
edge[ecnt].w = w;
edge[ecnt].to = to;
head[pre] = ecnt++;
}
void init() {
ecnt = 0;
memset (head, -1, sizeof (head));
}
///now dijkstra
unsigned int dis[MAXN], n, m, pre, to, w;
bool vis[MAXN];
struct Node {
int id;
bool operator < (const Node &b) const{
return dis[id] > dis[b.id];
}
}node;
priority_queue <Node> que;
int dijkustra(int st, int ed) {
while (que.size()) que.pop();
memset (dis, -1, sizeof (dis));
memset (vis, 0, sizeof (vis));
int now = st;
dis[now]= 0, node.id = now, que.push(node);
while (que.size()) {
now = que.top().id;
que.pop();
if (vis[now]) continue;
for (int i = head[now]; i != -1; i = edge[i].nxt) {
to = edge[i].to;
if (dis[to] > dis[now] + edge[i].w) {
dis[to] = dis[now] + edge[i].w;
if (!vis[to]) {
node.id = to;
que.push(node);
}
}
}
vis[now] = 1;
}
return dis[ed];
}
///dijkstra end;
void getin() {
init();
for (int i = 0; i < m; ++i) {
scanf("%d%d%d", &pre, &to, &w);
addedge(pre, to, w);
addedge(to, pre, w);
}
}
int main() {
while (scanf("%d%d", &n, &m) == 2 && (m || n)) {
getin();
printf("%d\n", dijkustra(1, n));
}
return 0;
}
update: 队列优化 Bellman-Ford / spfa
#include <stdio.h>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int MAX_N = 111, MAX_M = 1e5+10, INF = 0x3f3f3f;
int n, m, u, v, w, cnt;
int head[MAX_N], dis[MAX_N];
bool used[MAX_N];
struct Edge {
int to, nxt, w;
}edge[MAX_M << 1];
queue <int> que;
void add_edge(int pre, int to, int w) {
edge[cnt].to = to;
edge[cnt].w = w;
edge[cnt].nxt = head[pre];
head[pre] = cnt++;
}
void init() {
memset (head, -1, sizeof (head));
memset (used, 0, sizeof (used));
memset (dis, 0x3f, sizeof (dis));
cnt = 0;
while (que.size()) que.pop();
return ;
}
void getin() {
for (int i = 0; i < m; ++i) {
cin >> u >> v >> w;
add_edge(u, v, w);
add_edge(v, u, w);
}
return ;
}
int spfa (int st, int ed) {
int now;
used[st] = 1, dis[st] = 0;
que.push(st);
while (que.size()) {
now = que.front(), que.pop();
used[now] = 0;
for (int i = head[now]; i != -1; i = edge[i].nxt) {
if (dis[now] + edge[i].w < dis[edge[i].to]) {
dis[edge[i].to] = dis[now] + edge[i].w;
if (!used[edge[i].to]) {
used[edge[i].to] = 1;
que.push(edge[i].to);
}
}
}
}
return dis[ed];
}
int main() {
while (cin >> n >> m && (m || n)) {
init();
getin();
printf("%d\n", spfa(1, n));
}
return 0;
}
2018-02-03
2018-02-18: add spfa.