HDU 1385【两点间最短路, DIJK + 记录路径】
2011-04-07 16:23
281 查看
题目: http://acm.hdu.edu.cn/showproblem.php?pid=1385
解题思路:
对每一个询问, 跑一次dijkstra算法, 麻烦的是题目要求输出路径, 有多组解时还要是字典序最小的那条. 代码复杂了点, 但思路很简单, 用一个全局变题Path[]来记录父结点就可以了, 即前一个结点, 如 : Path[i] 表示 当前点 i 是由 Path[i] 得来的. DIJK跑完后, 可以从终点向前一直寻找前一个结点, 直到遇到始点, 可以得到一条完整的路径.
当有多组解时, 在松驰时候要加多一个判定条件, 判断当前得出的路径的字典序是否小于以前的就可以了.
解题思路:
对每一个询问, 跑一次dijkstra算法, 麻烦的是题目要求输出路径, 有多组解时还要是字典序最小的那条. 代码复杂了点, 但思路很简单, 用一个全局变题Path[]来记录父结点就可以了, 即前一个结点, 如 : Path[i] 表示 当前点 i 是由 Path[i] 得来的. DIJK跑完后, 可以从终点向前一直寻找前一个结点, 直到遇到始点, 可以得到一条完整的路径.
当有多组解时, 在松驰时候要加多一个判定条件, 判断当前得出的路径的字典序是否小于以前的就可以了.
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <map> using namespace std; const int MAX = 1000 + 1; int N; int Cost[MAX][MAX]; int Tax[MAX]; int Dis[MAX]; int Path[MAX]; void initInput() { for(int i = 1; i <= N; ++i) { for(int j = 1; j <= N; ++j) scanf("%d", &Cost[i][j]); } for(int i = 1; i <= N; ++i) scanf("%d", &Tax[i]); } struct comp { bool operator () (const int i, const int j) { return Dis[i] > Dis[j]; } }; bool compare(int e1, int e2) { stack<int> path1; stack<int> path2; path2.push(e1); while(e1 != Path[e1]) { path1.push(e1); e1 = Path[e1]; } path2.push(e1); while(e2 != Path[e2]) { path2.push(e2); e2 = Path[e2]; } while(!path1.empty() && !path2.empty()) { if(path1.top() != path2.top()) return path1.top() < path2.top(); path1.pop(); path2.pop(); } return path1.size() < path2.size(); } bool relax(int from, int to) { int c = Dis[from] + Cost[from][to] + Tax[to]; if(Cost[from][to] != -1 && c <= Dis[to]) { if(c == Dis[to] && compare(to, from)) return false; Dis[to] = c; Path[to] = from; return true; } else return false; } void dijk(const int start, const int end) { memset(Dis, 0x7f, sizeof(Dis)); memset(Path, 0x7f, sizeof(Path)); int endTax = Tax[end]; Tax[end] = 0; Path[start] = start; priority_queue<int, vector<int>, comp> que; Dis[start] = 0; que.push(start); while(!que.empty()) { int f = que.top(); que.pop(); for(int i = 1; i <= N; ++i) { if(i != f && relax(f, i)) { que.push(i); } } } Tax[end] = endTax; } void run() { int start, end; int f, t; while(scanf("%d%d", &start, &end) == 2 && start != -1 && end != -1) { dijk(start, end); stack<int> path; path.push(end); f = end; while(f != start) { path.push(Path[f]); f = Path[f]; } printf("From %d to %d :\n", start, end); printf("Path: %d", path.top()); path.pop(); while(!path.empty()) { printf("-->%d", path.top()); path.pop(); } printf("\nTotal cost : %d\n\n", Dis[end]); } } int main() { freopen("in.txt","r",stdin); while(scanf("%d", &N) == 1 && N) { initInput(); run(); } return 0; }
相关文章推荐
- 最短路 + 记录路径 之 zoj 1456 Minimum Transport Cost (hdu 1385)
- hdu 1385 Minimum Transport Cost(最短路+记录路径)
- HDU 1385 Minimum Transport Cost【最短路之路径记录】
- HDU1385 Minimum Transport Cost(最短路输出路径)
- HDU 1385 Minimum Transport Cost(floyd)(记录路径)
- hdu-1385-floyd记录路径
- hdu 1385 Minimum Transport Cost(floyd && 记录路径)
- hdu 1385 spfa和floyd,dijkstra记录最短最小字典序的路径
- HDU 1385 Minimum Transport Cost(folyd+记录路径)
- HDU - 1385 Minimum Transport Cost(最短路+最小字典序路径)
- HDU 1385 Minimum Transport Cost(最短路Floyd+标记路径)
- *HDU 1385 最短路 路径
- Minimum Transport Cost hdu 1385(最短路 + 路径保存 + stack)
- hdu 1385 Minimum Transport Cost 最短路加路径输出
- hdu 1385(求出最短路并输出最短路径)
- hdu 1385 Minimum Transport Cost--Floyd算法+点权值+记录路径
- hdu 2544 最短路(两点间最短路径)
- hdu 1385(最短路+输出路径)
- HDU1385 Floyd加正序记录路径
- HDU 1385 Minimum Transport Cost (Floyd求最短路径+记录字典序路径)