poj 3255 dijstra求次短路
2015-08-10 14:07
579 查看
无负权边,所以可以用dijstra来求次短路,过程和求最短路一样,反复揣摩求次短路的过程有助于更深入的理解dijstra。
O(n^2)的写法(500ms):
优先队列优化的写法(110ms):
优化了速度就是不一样!
O(n^2)的写法(500ms):
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> using namespace std; const int INF = 9999999; const int N = 5001; const int M = 200000; int head ; int dist [2]; bool visit [2]; int n, m, e; struct Edge { int v, next, w; } edge[M]; void addEdge( int u, int v, int w ) { edge[e].v = v; edge[e].w = w; edge[e].next = head[u]; head[u] = e++; } void dij( int s ) { memset( visit, false, sizeof(visit) ); memset( dist, 0x3f, sizeof(dist) ); dist[s][0] = 0; for ( int i = 1; i <= 2 * n; i++ ) { int u, flag, mincost = INF; for ( int j = 1; j <= n; j++ ) { for ( int k = 0; k <= 1; k++ ) { if ( !visit[j][k] && dist[j][k] < mincost ) { mincost = dist[j][k]; u = j; flag = k; } } } visit[u][flag] = 1; for ( int j = head[u]; j != -1; j = edge[j].next ) { int v = edge[j].v, w = edge[j].w; if ( !visit[v][0] && dist[v][0] > dist[u][flag] + w ) { dist[v][1] = dist[v][0]; dist[v][0] = dist[u][flag] + w; } else if ( !visit[v][1] && dist[v][1] > dist[u][flag] + w ) { dist[v][1] = dist[u][flag] + w; } } } } int main () { while ( scanf("%d%d", &n, &m) != EOF ) { e = 0; memset( head, -1, sizeof(head) ); while ( m-- ) { int u, v, w; scanf("%d%d%d", &u, &v, &w); addEdge( u, v, w ); addEdge( v, u, w ); } dij(1); printf("%d\n", dist [1]); } return 0; }
优先队列优化的写法(110ms):
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <queue> using namespace std; const int INF = 9999999; const int N = 5001; const int M = 200000; int head ; int dist [2]; bool visit [2]; int n, m, e; struct Edge { int v, next, w; } edge[M]; void addEdge( int u, int v, int w ) { edge[e].v = v; edge[e].w = w; edge[e].next = head[u]; head[u] = e++; } struct Node { int nn, tt, len; Node(){} Node( int _nn, int _tt, int _len ) { nn = _nn, tt = _tt, len = _len; } bool operator < ( const Node & o ) const { return len > o.len; } }; priority_queue<Node> q; void dij( int s ) { memset( visit, 0, sizeof(visit) ); memset( dist, 0x3f, sizeof(dist) ); dist[s][0] = 0; q.push( Node( s, 0, 0 ) ); while ( !q.empty() ) { Node cur = q.top(); q.pop(); if ( visit[cur.nn][cur.tt] ) continue; visit[cur.nn][cur.tt] = true; for ( int i = head[cur.nn]; i != -1; i = edge[i].next ) { int v = edge[i].v, w = edge[i].w; if ( !visit[v][0] && cur.len + w < dist[v][0] ) { dist[v][1] = dist[v][0]; dist[v][0] = cur.len + w; q.push( Node( v, 1, dist[v][1] ) ); q.push( Node( v, 0, dist[v][0] ) ); } else if ( !visit[v][1] && cur.len + w < dist[v][1] ) { dist[v][1] = cur.len + w; q.push( Node( v, 1, dist[v][1] ) ); } } } } int main () { while ( scanf("%d%d", &n, &m) != EOF ) { e = 0; memset( head, -1, sizeof(head) ); while ( m-- ) { int u, v, w; scanf("%d%d%d", &u, &v, &w); addEdge( u, v, w ); addEdge( v, u, w ); } dij(1); printf("%d\n", dist [1]); } return 0; }
优化了速度就是不一样!
相关文章推荐
- 史上最详细的JavaScript事件使用指南
- Servlet+jsp实现简单购物车
- 在C#中实现Json的序列化与反序列化
- js关于for循环里的setTimeout
- JS中数组Array的用法{转载}
- $.parseJSON()方法
- JS 对输入框文本正在输入中校验
- 关于JSP源码泄漏问题的总结分析
- JS和JSP的区别
- js 上传图片预览
- JS中的substring和substr函数的区别
- JS注入操作页面对象
- JSON的传输数据报错
- javascript 中concat与push的区别
- javascript与Python快速排序实例对比
- javascript密码强度校验代码(两种方法)
- javascript实现数组内值索引随机化及创建随机数组的方法
- 关于 CommonJS AMD CMD UMD 规范的差异总结
- 在页面载入的时候,执行js
- 使用artTemplate绑定json数据