dijkstra + 链式前向星 + 优先队列
作者:互联网
#include <iostream> #include <queue> #include <cstring> #include <algorithm> using namespace std; const int N = 1005; const int M = 2*10005; const int INF = 1e8; int dist[N],head[N]; bool flag[N]={0}; typedef pair<int,int> pii; int n, m, cnt = 0; struct Edge{ // 创建 边 的结构体 int to, w, next; }edge[M]; void add_edge(int u, int v, int w) { // 链式前向星 (静态链式邻接表) 头插法 edge[cnt].to = v; // to 表示 其终点 edge[cnt].w = w; // w 表示其 权值 edge[cnt].next = head[u]; // next 表示 以 u 为起点的上一条边的编号 head[u] = cnt ++; // 更新以 u 为起点的边的编号 cnt 表示编号 } void dijkstra(int u) { // 优先队列优化 相当于 把之前的每次找最小距离的步骤 用优先队列直接找出来了 priority_queue< pii, vector<pii>, greater<pii> > q; // 优先队列 以 pii 的 first 大小(若相等,则比较second)升序排列 for (int i=1; i<=n; i++) dist[i] = INF; // 初始化 q.push({dist[u],u}); // 将 dist[u] u 组成的 pii 放入 q 中 dist[u] = 0; // 自己到自己的 距离初始化为 0 while (!q.empty()) { pii it = q.top(); q.pop(); int st = it.second; // st 表示该点 if (flag[st]) continue; // flag[st] = 1 表示该 点已找到最短距离 continue 无需再重复处理 flag[st] = 1; // 将其标记为 1 说明 已经处理过 for (int i=head[st]; i!=-1; i=edge[i].next) { // 遍历该点的 连接边 i 为 其编号 int j = edge[i].to; // j 为 以 st 为起点的边的 终点 if (!flag[j] && dist[j] > dist[st] + edge[i].w) { // 若其未被标记 且 由源点到j的距离 大于 由源点到st的距离 + 以st为起点的边的权值 则更新 dist[j] dist[j] = dist[st] + edge[i].w; q.push({dist[j],j}); // 将其 加入 优先队列 q 中 } } } } int main(){ int u,v,w,a,b; while (cin >> n >> m >> u >> v) { memset(head,-1,sizeof(head)); memset(dist,INF,sizeof(head)); memset(flag,0,sizeof(flag)); while (m--) { cin >> a >> b >> w; add_edge(a,b,w); add_edge(b,a,w); // 无向边 } dijkstra(u); if (dist[v] == INF) cout << -1 << endl; else cout << dist[v] << endl; } return 0; }
标签:head,dist,int,cnt,dijkstra,edge,链式,include,前向星 来源: https://www.cnblogs.com/jianping5/p/16030108.html