【裸单源最短路:Dijkstra算法两种版本】hdu 1874 畅通工程续
2015-08-29 23:33
453 查看
Source : hdu 1874 畅通工程续
某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
Input
本题目包含多组数据,请处理到文件结束。
每组数据第一行包含两个正整数N和M(0 < N <200,0 < M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B < N,A!=B,0< X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T< N),分别代表起点和终点。
Output
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
3 3
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2
Sample Output
2
-1
方法一:Dijkstra算法 + 堆优化 O(mlogn)
方法二:Dijkstra算法 O(n^2)
加粗
斜体
引用
插入链接
插入代码
插入图片
提升标题
有序列表
无序列表
横线
撤销
重做
http://acm.hdu.edu.cn/showproblem.php?pid=1874
Problem Description某省自从实行了很多年的畅通工程计划后,终于修建了很多路。不过路多了也不好,每次要从一个城镇到另一个城镇时,都有许多种道路方案可以选择,而某些方案要比另一些方案行走的距离要短很多。这让行人很困扰。
现在,已知起点和终点,请你计算出要从起点到终点,最短需要行走多少距离。
Input
本题目包含多组数据,请处理到文件结束。
每组数据第一行包含两个正整数N和M(0 < N <200,0 < M<1000),分别代表现有城镇的数目和已修建的道路的数目。城镇分别以0~N-1编号。
接下来是M行道路信息。每一行有三个整数A,B,X(0<=A,B < N,A!=B,0< X<10000),表示城镇A和城镇B之间有一条长度为X的双向道路。
再接下一行有两个整数S,T(0<=S,T< N),分别代表起点和终点。
Output
对于每组数据,请在一行里输出最短需要行走的距离。如果不存在从S到T的路线,就输出-1.
题意
告诉你起点和终点,求最短路径长度,没有的话输出-1示例
Sample Input3 3
0 1 1
0 2 3
1 2 1
0 2
3 1
0 1 1
1 2
Sample Output
2
-1
思路
单源最短路经典题目,由于n比较小,这里用两个版本的迪杰斯特拉算法都跑了一遍,注意第二个版本重边的处理!方法一:Dijkstra算法 + 堆优化 O(mlogn)
方法二:Dijkstra算法 O(n^2)
参考代码1 Dijkstra算法 + 堆优化 O(mlogn)
/*Dijkstra算法 + 堆优化O(ElogE)*/ #include<bits/stdc++.h> #define clr(k,v) memset(k,v,sizeof(k)) #define INF 0x3f3f3f3f using namespace std; const int _max = 200 + 10; int n,m,u,v,w,st,ed; struct qnode{ int v,c; qnode(int _v = 0,int _c = 0):v(_v),c(_c){} bool operator < (const qnode &r)const{ return c > r.c; } }; struct Edge{ int v,cost; Edge(int _v = 0,int _cost = 0):v(_v),cost(_cost){} }; vector<Edge>E[_max]; bool vis[_max]; int dist[_max]; //点的编号从1开始 void Dijkstra(int n,int start){ clr(vis,0); for(int i = 1; i <= n; ++ i) dist[i] = INF; priority_queue<qnode>pq; while(!pq.empty()) pq.pop(); dist[start] = 0; pq.push(qnode(start,0)); qnode tmp; while(!pq.empty()){ tmp = pq.top(); pq.pop(); int u = tmp.v; if(vis[u]) continue; vis[u] = true; for(int i = 0; i < E[u].size(); ++ i){ int v = E[tmp.v][i].v; int cost = E[u][i].cost; if(!vis[v] && dist[v] > dist[u] + cost){ dist[v] = dist[u] + cost; pq.push(qnode(v,dist[v])); } } } } void addedge(int u,int v,int w){ E[u].push_back(Edge(v,w)); E[v].push_back(Edge(u,w));//无向图注意push两次,题目说是双向道路!!! } int main(){ #ifndef ONLINE_JUDGE freopen("input.txt","r",stdin); #endif // ONLINE_JUDGE while(scanf("%d%d",&n,&m) == 2){ for(int i = 0; i <= n; ++ i) E[i].clear();//初始化 for(int i = 0; i < m; ++ i){ scanf("%d%d%d",&u,&v,&w); //邻接表存储,重边不用考虑的! addedge(u+1,v+1,w);//编号从1开始 } scanf("%d%d",&st,&ed); Dijkstra(n,st+1); if(dist[ed + 1] == INF) puts("-1"); else printf("%d\n",dist[ed + 1]); } return 0; }
参考代码2 Dijkstra算法 O(n^2)
/*Dijkstra算法 + 邻接矩阵O(n^2)*/ #include<bits/stdc++.h> #define clr(k,v) memset(k,v,sizeof(k)) #define INF 0x3f3f3f3f using namespace std; const int _max = 200 + 10; int u,v,w,n,m,st,ed; bool vis[_max]; int pre[_max];//记录源节点beg到i路径上的父节点,pre[beg] = -1 int lowcost[_max],cost[_max][_max]; void Dijkstra(int beg){//编号0-n-1 for(int i = 0;i < n; ++ i){ lowcost[i] = INF;vis[i] = false;pre[i] = -1; } lowcost[beg] = 0; for(int j = 0; j < n; ++ j){ int k = -1; int Min = INF; for(int i = 0; i < n; ++ i) if(!vis[i] && lowcost[i] < Min){ Min = lowcost[i]; k = i; } if(k == -1) break; vis[k] = true; for(int i = 0; i < n; ++ i) if(!vis[i] && lowcost[k] + cost[k][i] < lowcost[i]){ lowcost[i] = lowcost[k] + cost[k][i]; pre[i] = k; } } } int main(){ #ifndef ONLINE_JUDGE freopen("input.txt","r",stdin); #endif // ONLINE_JUDGE while(scanf("%d%d",&n,&m) == 2){ clr(cost,INF); int c = INF; for(int i = 0; i < m; ++ i){ scanf("%d%d%d",&u,&v,&w);//编号从0开始 if(cost[u][v] > w) cost[u][v] = cost[v][u] = w;//重边处理,邻接矩阵存储时 } scanf("%d%d",&st,&ed); Dijkstra(st); if(lowcost[ed] == INF) puts("-1"); else printf("%d\n",lowcost[ed]); } return 0; }
加粗
Ctrl + B
斜体
Ctrl + I
引用
Ctrl + Q
插入链接
Ctrl + L
插入代码
Ctrl + K
插入图片
Ctrl + G
提升标题
Ctrl + H
有序列表
Ctrl + O
无序列表
Ctrl + U
横线
Ctrl + R
撤销
Ctrl + Z
重做
Ctrl + Y
相关文章推荐
- 基于Java实现的Dijkstra算法示例
- Dijkstra和floyd——求单源点最短路径
- 初学图论-Dijkstra单源最短路径算法
- 初学图论-Dijkstra单源最短路径算法基于优先级队列(Priority Queue)的实现
- Dijkstra算法的粗略学习
- 【高手回避】poj3268,一道很水的dijkstra算法题
- poj2387 Til the Cows Come Home—Dijkstra模板
- Dijkstra 算法实现及问题
- Djkstra
- 最短路
- 一个人的旅行
- HDU 2544
- Dijkstra算法学习笔记(1)
- 最短路?那是什么 °▽°
- POJ 2263
- 单源最短路深度分析
- UVa Problem 10039 Railroads (铁路)
- Dijkstra's Algorithm of shortest path
- Dijkstra最短路径算法
- 最短路径问题迪杰斯特拉(Dijkstra)Android 测试