暑假-最短路(Bellman-ford、spfa)-C - Minimum Transport Cost
2015-08-18 20:14
363 查看
题意:有n个城市,然后给你n*n的矩阵,map[i][j]代表:值为-1即表示没有从i到j的路,
否则存在i到j的路,并且路费的map[i][j]的值,然后每经过一个城市都要交税(除了起点和终点外)
n等于0时程序结束,然后给你起点和终点,输出从起点和终点的最小费用和路径。
费用=路费+税。
注意:若存在几条路径的费用一样,则要输出字典序最小的那条。
(如:从1->3的费用为3,从1->2->3的费用也是3,那么就要输出第二条路径)
思路:SPFA,Floy,Dijkstra
Floy最方便,其他两个在输出字典序最小的那条路比较麻烦。
SPFA算法:
<在输出字典序最小的路径上面卡死了,WA了8次。实在无力去找题解才发现可以用直接把2条路径放出
在判断哪个是字典序最小,T T>
否则存在i到j的路,并且路费的map[i][j]的值,然后每经过一个城市都要交税(除了起点和终点外)
n等于0时程序结束,然后给你起点和终点,输出从起点和终点的最小费用和路径。
费用=路费+税。
注意:若存在几条路径的费用一样,则要输出字典序最小的那条。
(如:从1->3的费用为3,从1->2->3的费用也是3,那么就要输出第二条路径)
思路:SPFA,Floy,Dijkstra
Floy最方便,其他两个在输出字典序最小的那条路比较麻烦。
SPFA算法:
<在输出字典序最小的路径上面卡死了,WA了8次。实在无力去找题解才发现可以用直接把2条路径放出
在判断哪个是字典序最小,T T>
#include<iostream> #include<cstring> #include<queue> using namespace std; const int MAXN = 105; #define INF 0x3f3f3f3f//无穷大 int inq[MAXN], tax[MAXN], map[MAXN][MAXN];//点是否算过,税,路费 int path[MAXN][MAXN], dist[MAXN][MAXN];//保存路径,值 int n; bool chang(int v0, int u, int v)//判断字典序是否是最小 {//从v0->...->v的路径,和v0->...->u->v的路径比较取字典序小的 int p1[MAXN], p2[MAXN]; //v0->...->v的路径,v0->...->u->v的路径 int len1 = 0, len2 = 0, tmp; memset(p1, 0, sizeof(p1)); memset(p2, 0, sizeof(p2)); p1[len1] = v;//v0->...->v的路径 tmp = path[v0][v]; while (tmp != v0) { p1[++len1] = tmp; tmp = path[v0][tmp]; } p1[++len1] = tmp; p2[len2] = v;// v0->...->u->v的路径 tmp = u; while (tmp != v0) { p2[++len2] = tmp; tmp = path[v0][tmp]; } p2[++len2] = tmp; while (p1[len1] == p2[len2])//从开始一一判断 { len1--; len2--; } return p2[len2]<p1[len1]; } void SPFA(int v0)//SPFA算法 { int i, u; queue<int>q; for (i = 1; i <= n; i++) { inq[i] = 0; dist[v0][i] = map[v0][i]; path[v0][i] = v0; } dist[v0][v0] = 0; for (i = 1; i <= n; i++) { if (dist[v0][i] != INF) { q.push(i); inq[i] = 1; } } while (!q.empty()) { u = q.front(); q.pop(); inq[u]--; for (int v = 1; v <= n; v++) { if (dist[v0][v]>(dist[v0][u] + map[u][v] + tax[u])) { dist[v0][v] = (dist[v0][u] + map[u][v] + tax[u]); path[v0][v] = u; if (!inq[v]) { q.push(v); inq[v]++; } } else if (dist[v0][v] == (dist[v0][u] + map[u][v] + tax[u])) { if (chang(v0, u, v))//费用相同判断路径是否满足字典序最小 { path[v0][v] = u; } } } } } int main() { while (cin >> n) { if (!n) { break; } int Start, End; for (int i = 1; i <= n; i++)//路费 { for (int j = 1; j <= n; j++) { cin >> map[i][j]; if (map[i][j] == -1)//无路 { map[i][j] = INF; } } } for (int i = 1; i <= n; i++)//对应城市的税 { cin >> tax[i]; } for (int i = 1; i <= n; i++)//预先把所有求出来。 { SPFA(i); } while (cin >> Start >> End)//开始和结束,然后按照案例输出 { if (Start == -1 && End == -1) { break; } if (Start == End) { cout << "From " << Start << " to " << End << " :" << endl; cout << "Path: " << Start << endl; cout << "Total cost : " << 0 << endl << endl; continue; } int shorttest[MAXN], k = 0; cout << "From " << Start << " to " << End << " :" << endl; cout << "Path: "; shorttest[k] = End; while (path[Start][shorttest[k]] != Start) { k++; shorttest[k] = path[Start][shorttest[k - 1]]; } k++; shorttest[k] = Start; for (int j = k; j > 0; j--) { cout << shorttest[j] << "-->"; } cout << shorttest[0] << endl; cout << "Total cost : " << dist[Start][End] << endl << endl; } } return 0; }
相关文章推荐
- 总线设备驱动模型——驱动篇
- Codeforces Gym 100650D Queens, Knights and Pawns 暴力
- 黑马程序员——视频学习过程4
- using声明和using指示、std::move和std::forward
- 10个前端开发必备的工具或使用方法
- HDOJ 1047 Integer Inquiry (多个大数求和)
- 图形验证码(JSP+Servlet)
- UVA 11997 K Smallest Sums
- Python nltk -- Sinica Treebank
- BZOJ1042
- Delphi 在任务栏隐藏程序图标
- leetcode -day31 Subsets I II
- Autofac 的构造函数注入方式
- NBUT 1220 SPY
- 总线设备驱动模型——设备篇
- Unable to execute dex: Multiple dex files define Lorg/ap (
- 如何激活一个window/dialog && 不能直接对Dialog Box使用SetFocus
- [algorithm] graph algorithm
- N-Queens N皇后问题 DFS
- leetcode之路026 Remove Duplicates from Sorted Arrayy