poj 2387 最短路径 **dijkstra模板
来源:互联网 发布:淘宝评价语20字 编辑:程序博客网 时间:2024/06/06 20:27
真是一道神奇的题目,已经注意了重边的问题,但是还是各种WA
后来不用优先队列写了dijkstra算法,AC了
然后又改用优先队列写,AC了。。好奇怪,为什么一开始各种WA呢??不明白
#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int INF = 1000000000;const int MAXN = 2570;const int maxn = MAXN;///全局变量 和 函数int T, N;int g[maxn][maxn];struct node{int id;int dist;};int n;bool operator < (const node& t1, const node& t2){return t1.dist > t2.dist;}int solve(int start, int dest, int type){int i, j;bool done[maxn];int d[maxn];if (type == 0){for (i = 1; i <= n; i++){d[i] = INF;}d[start] = 0;memset(done, false, sizeof(done));/*for (i = 1; i <= n - 1; i++){int minpos = -1;int minval = INF;for (j = 1; j <= n; j++){if (!done[j] && d[j] < minval){minval = d[j];minpos = j;}}if (minpos == -1)return d[dest];done[minpos] = true;for (j = 1; j <= n; j++){if (g[minpos][j] != INF && d[j] > d[minpos] + g[minpos][j]){d[j] = d[minpos] + g[minpos][j];}}}*/node temp;temp.id = start, temp.dist = d[start];priority_queue<node> q;q.push(temp);while (!q.empty()){int curid = q.top().id;q.pop();if (done[curid])continue;done[curid] = true;for (i = 1; i <= n; i++){if (g[curid][i] != INF && d[i] > d[curid] + g[curid][i]){d[i] = d[curid] + g[curid][i];node tmp;tmp.id = i;tmp.dist = d[i];q.push(tmp); }}}}return d[dest];}int main(){///变量定义int i, j;while (scanf("%d %d", &T, &N) != EOF){n = N;for (i = 0; i < maxn; i++)for (j = 0; j < maxn; j++)g[i][j] = INF;for (i = 0; i < T; i++){int from, to, dist;scanf("%d %d %d", &from, &to, &dist);if (g[from][to] > dist){g[from][to] = g[to][from] = dist;}}int ans = solve(N, 1, 0);printf("%d\n", ans);}///结束return 0;}
再贴个邻接链表加优先队列的算法实现,显然速度比邻接矩阵要快的多
#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int INF = 1000000000;const int MAXN = 201000;const int maxn = MAXN;///全局变量 和 函数int t, n;int first[maxn];int u[maxn], v[maxn], w[maxn], next[maxn];int d[maxn];int done[maxn];struct Node{ int id; int dist;};bool operator < (const Node& t1, const Node& t2){ return t1.dist > t2.dist;}int dijkstra(int start, int dest){ int i, j; for(i = 1; i <= n; i++) d[i] = INF; d[start] = 0; memset(done, false, sizeof(done)); Node node; node.id = start; node.dist = d[start]; priority_queue<Node> q; q.push(node); while(!q.empty()) { Node tmp = q.top(); q.pop(); int curid = tmp.id; if(done[curid]) continue; done[curid] = true; for(int e = first[curid]; e != -1; e = next[e]) { if(d[v[e]] > d[curid] + w[e]) { d[v[e]] = d[curid] + w[e]; Node temp; temp.id = v[e]; temp.dist = d[v[e]]; q.push(temp); } } } return d[dest];}int main(){///变量定义int i, j; while(scanf("%d %d", &t, &n) != EOF) { for(i = 1; i <= n; i++) { first[i] = -1; } int cnt = 0; for(i = 0; i < t; i++) { int from, to, weight; scanf("%d %d %d", &from, &to, &weight); u[cnt] = from; v[cnt] = to; w[cnt] = weight; next[cnt] = first[u[cnt]]; first[u[cnt]] = cnt; cnt++; u[cnt] = to; v[cnt] = from; w[cnt] = weight; next[cnt] = first[u[cnt]]; first[u[cnt]] = cnt; cnt++; } int ans = dijkstra(n, 1); printf("%d\n", ans); }///结束return 0;}
再贴一个 bellman ford算法,不同之处在于采用FIFO的队列
依据:如果存在最短路,则必然在有限次数(至多n-1)此内不能再进行松弛,详细见CLRS
#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int INF = 1000000000;const int MAXN = 201000;const int maxn = MAXN;///全局变量 和 函数int t, n;int first[maxn];int u[maxn], v[maxn], w[maxn], next[maxn];int d[maxn];int done[maxn];struct Node{ int id; int dist;};bool operator < (const Node& t1, const Node& t2){ return t1.dist > t2.dist;}int dijkstra(int start, int dest){ int i, j; for(i = 1; i <= n; i++) d[i] = INF; d[start] = 0; memset(done, false, sizeof(done)); queue<int> qq; bool inq[maxn]; memset(inq, false, sizeof(inq)); qq.push(start); while(!qq.empty()) { int curid = qq.front(); qq.pop(); inq[curid] = false; for(int e = first[curid]; e != -1; e = next[e]) { if(d[v[e]] > d[curid] + w[e]) { d[v[e]] = d[curid] + w[e]; if(!inq[v[e]]) { inq[v[e]] = true; qq.push(v[e]); } } } } return d[dest];}int main(){///变量定义int i, j; while(scanf("%d %d", &t, &n) != EOF) { for(i = 1; i <= n; i++) { first[i] = -1; } int cnt = 0; for(i = 0; i < t; i++) { int from, to, weight; scanf("%d %d %d", &from, &to, &weight); u[cnt] = from; v[cnt] = to; w[cnt] = weight; next[cnt] = first[u[cnt]]; first[u[cnt]] = cnt; cnt++; u[cnt] = to; v[cnt] = from; w[cnt] = weight; next[cnt] = first[u[cnt]]; first[u[cnt]] = cnt; cnt++; } int ans = dijkstra(n, 1);//bellman ford非dij printf("%d\n", ans); }///结束return 0;}
Floyd 算法 超时了 TLE
#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int INF = 10000000;const int MAXN = 2010;const int maxn = MAXN;///全局变量 和 函数int t, n;//int first[maxn];//int u[maxn], v[maxn], w[maxn], next[maxn];//int d[maxn];//int done[maxn];int dd[maxn][maxn]; //Floyd算法阵void Floyd(){ int i, j, k; for(k = 1; k <= n; k++) { for(i = 1; i <= n; i++) { for(j = 1; j <= n; j++) { // if(dd[i][j] < INF && dd[k][j] < INF) // { if(dd[i][j] > dd[i][k] + dd[k][j]) dd[i][j] = dd[i][k] + dd[k][j]; // } } } }}int main(){///变量定义int i, j; while(scanf("%d %d", &t, &n) != EOF) { for(i = 1; i <= n; i++) { for(j = 1; j <= n; j++) { if(i != j) dd[i][j] = INF; else dd[i][j] = 0; } } for(i = 0; i < t; i++) { int from, to, weight; scanf("%d %d %d", &from, &to, &weight); if(dd[from][to] > weight) dd[from][to] = dd[to][from] = weight; } Floyd(); int ans = dd[n][1]; printf("%d\n", ans); }///结束return 0;}
最后再贴一个大神的dij的模板,非常好用
#include <iostream>#include <vector>#include <map>#include <list>#include <set>#include <deque>#include <stack>#include <queue>#include <algorithm>#include <cmath>#include <cctype>#include <cstdio>#include <iomanip>#include <cmath>#include <cstdio>#include <iostream>#include <string>#include <sstream>#include <cstring>#include <queue>using namespace std;///宏定义const int INF = 10000000;const int MAXN = 1257;const int maxn = MAXN;///全局变量 和 函数struct Edge{int from;int to;int dist;};struct HeapNode{int d, u;bool operator < (const HeapNode& rhs) const{return d > rhs.d;}};struct Dijkstra{int n, m; //点数和边数vector<Edge> edges; //边列表vector<int> G[maxn]; //每个结点出发的边编号bool done[maxn]; //是否已永久编号int d[maxn]; //s到各个点的距离int p[maxn]; //最短路中的上一条边 (打印结果用)void init(int n){this->n = n;for (int i = 0; i <= n; i++)G[i].clear();edges.clear();}void AddEdge(int from, int to, int dist){ Edge tmp; tmp.from = from; tmp.to = to; tmp.dist = dist;edges.push_back(tmp);m = edges.size();G[from].push_back(m - 1);}void dijkstra(int s){priority_queue<HeapNode> Q;for (int i = 0; i <= n; i++)d[i] = INF;d[s] = 0;memset(done, 0, sizeof(done));HeapNode tmp;tmp.d = 0;tmp.u = s;Q.push(tmp);while (!Q.empty()){HeapNode x = Q.top();Q.pop();int u = x.u;if (done[u])continue;done[u] = true;for (int i = 0; i < G[u].size(); i++){Edge &e = edges[G[u][i]];if (d[e.to] > d[u] + e.dist){d[e.to] = d[u] + e.dist;p[e.to] = G[u][i];HeapNode temp;temp.d = d[e.to];temp.u = e.to;Q.push(temp);}}}}};///int T, N;int main(){///变量定义int i, j; while(scanf("%d %d", &T, &N) != EOF) { Dijkstra dij; dij.init(N); for(i = 0; i < T; i++) { int from, to, dist; scanf("%d %d %d", &from, &to, &dist); dij.AddEdge(from, to, dist); dij.AddEdge(to, from, dist); } dij.dijkstra(N); printf("%d\n", dij.d[1]); }///结束return 0;}
- poj 2387 最短路径 **dijkstra模板
- poj 2387 最短路径Dijkstra
- POJ 2387 最短路径模板
- Dijkstra最短路径模板2
- 最短路径Dijkstra算法模板
- ACM模板 dijkstra,最短路径
- 最短路径之 Dijkstra模板
- dijkstra 最短路径算法模板
- 最短路径-Dijkstra(poj 1135)
- poj 1797 dijkstra最短路径
- 最短路径 Dijkstra
- 最短路径-Dijkstra
- Dijkstra 最短路径
- Dijkstra 最短路径。
- 最短路径dijkstra
- 最短路径 Dijkstra
- Dijkstra最短路径
- Dijkstra 最短路径
- 编一个程序,对于给定a,b,c的值,求出一元二次方程a*x*x+b*x+c=0的二个实数根,如果没有实数根,则说明即可
- org.springframework.web.context.ContextLoaderListener
- 【环境】常用编辑工具配置
- java变量命名规则?
- c语言访问mysql数据库 包括BLOB字段的访问
- poj 2387 最短路径 **dijkstra模板
- 64位Ubuntu系统安装QQ2012
- glib和uclibc的区别
- strtol函数使用
- 学习笔记 I——排序
- Android消息机制
- 【源码】常用源代码集合
- ubuntu下最好用的截图软件shutter
- 操作系统经典书籍推荐