Node:最短路径之Dijkstra堆优化
2015-07-16 23:08
681 查看
#include <iostream> #include <stdio.h> #include <algorithm> #include <string.h> #include <stack> #include <queue> #define flush(arr,i) memset(arr,i,sizeof(arr)) #define INF 0xfffffff using namespace std; const int maxn=1010; //到节点的距离和第i个节点的前一个节点 int dis[maxn], pre[maxn]; //边集 int cost[maxn][maxn]; //是否在集合之中 bool vis[maxn]; struct Node { int nodeId; int len; }; Node heap[maxn]; int n, m, s, sz; /* 测试数据 --------- 8 14 6 6 5 1 6 4 3 6 7 6 5 3 3 5 4 1 7 4 1 7 2 4 4 2 9 3 4 1 3 1 4 1 2 1 7 8 14 2 8 2 3 2 2 -------- */ //数据录入和初始化 void initMap() { //没有进入集合 flush(vis, 0); sz = 0; scanf("%d%d%d", &n, &m, &s); int from, to, len; for(int i = 1; i <= n; i++) { dis[i] = INF; pre[i] = 0; for(int j = 1; j <= n; j++) cost[i][j] = INF; } for(int i = 0; i < m; i++) { scanf("%d%d%d",&from, &to, &len); printf("%c %c %d\n",from + 'r', to + 'r', len); cost[from][to] = cost[to][from] = len; 4000 } } //路径输出 void showPath(int cur) { if(pre[cur]) showPath(pre[cur]); printf("->%c", cur + 'r'); } /* //优化集中在这一部分 int getMinmunNode() { int maxCost = INF, pos = -1; for(int i = 1; i <= n; i++) if(!vis[i] && dis[i] < maxCost) { pos = i; maxCost = dis[i]; } //加入集合标记为1 vis[pos] = 1; return pos; } */ //-------------------------------------------------- //使用堆来进行优化:(用数组进行维护)堆从下标1开始 int getMinmNode() //最小堆 { int ret = heap[1].nodeId; //,第一个节点删除,最后一个放到第一个位置,之后向下调整 heap[1] = heap[sz--]; int cur = 1, son = 2; // 存在儿子比父亲小 while(son <= sz && (heap[son].len < heap[cur].len || heap[son+1].len < heap[cur].len)) { if(heap[son].len > heap[son+1].len) son++; swap(heap[son].len,heap[cur].len); swap(heap[son].nodeId,heap[cur].nodeId); //指针下移 cur = son; son*= 2; } return ret; } void deleteNode(int id) { int pos = -1; for(int i = 0; i < sz; i++) if(heap[i].nodeId == id) { pos = i; break; } if(pos != -1) { for(int i = pos; i < sz - 1; i++) heap[i] = heap[i + 1]; sz--; } } void insertNode(Node t) { //添加到最后一个节点,向上调整 heap[++sz] = t; int cur = sz, p = cur/2; while(p>=1) { //比父亲小的节点 if(heap[cur].len < heap[p].len) { swap(heap[cur].len,heap[p].len); swap(heap[cur].nodeId,heap[p].nodeId); } cur = p; p = cur/2; } } //---------------------------------------------------- void Dijkstra(int s) { dis[s] = 0; Node from; from.len = 0; from.nodeId = s; insertNode(from); //一共更新n次 while(sz) { //获取当前的is最小节点进行下一步更新 int cur = getMinmNode(); //输出当前选出的节点 printf("cur %c\n", cur + 'r'); for(int j = 0; j <= n; j++) //满足更新条件 if(dis[j] > dis[cur] + cost[cur][j]) { dis[j] = dis[cur] + cost[cur][j]; deleteNode(j); Node newNode; newNode.len = dis[j]; newNode.nodeId = j; insertNode(newNode); //维护路径 pre[j] = cur; //输出更新情况 printf("%c->%c:%d ", s + 'r', j + 'r', dis[j]); } printf("\n"); } for(int i = 1; i <= n; i++) { showPath(i); printf(" %d\n",dis[i]); } } int main() { freopen("data.txt","r",stdin); initMap(); Dijkstra(s); return 0; }
相关文章推荐
- Javascript SHA-1:Secure Hash Algorithm
- 基于Java实现的Dijkstra算法示例
- Dijkstra和floyd——求单源点最短路径
- [转]可视化的数据结构和算法
- 统计文件中不小于某一长度的单词的个数(泛型算法实现)
- Dijkstra算法的粗略学习
- 使用他人的MD5编码类,修改形成密码串
- Extracting Structured Data from Web Pages
- (译)Cocos2d_for_iPhone_1_Game_Development_Cookbook:1.13使用CCTexture2DMutable调换调色盘
- Java中3DES加密
- Refactoring Notes-Refactoring Methods(3)
- 图书馆管理程序~~不过貌似功能!!有空再修修
- trainging contest#2(2011成都现场赛)I BY Hyoga
- C/C++头文件包含内容概览
- 堆栈的应用(1) 平衡符号 C++实现
- 程序员编程艺术第一章、左旋转字符串
- 程序员编程艺术:第三章续、Top K算法问题的实现
- 程序员编程艺术:第四章、现场编写类似strstr/strcpy/strpbrk的函数
- 十四、第三章再续:快速选择SELECT算法的深入分析与实现
- 程序员编程艺术:第七章、求连续子数组的最大和