SPOJ 15. The Shortest Path 最短路径题解
2014-06-17 12:29
447 查看
本题就是给出一组cities,然后下面会询问,两个cities之间的最短路径。
属于重复询问的问题,暂时我只想到使用Dijsktra+heap实现了。
因为本题重复查询次数也不多,故此如果保存所有最短路径,那么是得不偿失了。
所以还是重复使用Dijsktra吧。
有没有更加好的办法处理重复查询问题呢?还没想到。
本算法纯粹手工打造了,不使用stl,代码很长很长,光打一遍就会手软的,呵呵。
原题:
You are given a list of cities. Each direct connection between two cities has its transportation cost (an integer bigger than 0). The goal is to find the paths of minimum cost between pairs of cities. Assume that the cost of each path (which is the sum of costs
of all direct connections belongning to this path) is at most 200000. The name of a city is a string containing characters a,...,z and is at most 10 characters long.
属于重复询问的问题,暂时我只想到使用Dijsktra+heap实现了。
因为本题重复查询次数也不多,故此如果保存所有最短路径,那么是得不偿失了。
所以还是重复使用Dijsktra吧。
有没有更加好的办法处理重复查询问题呢?还没想到。
本算法纯粹手工打造了,不使用stl,代码很长很长,光打一遍就会手软的,呵呵。
原题:
You are given a list of cities. Each direct connection between two cities has its transportation cost (an integer bigger than 0). The goal is to find the paths of minimum cost between pairs of cities. Assume that the cost of each path (which is the sum of costs
of all direct connections belongning to this path) is at most 200000. The name of a city is a string containing characters a,...,z and is at most 10 characters long.
Input
s [the number of tests <= 10] n [the number of cities <= 10000] NAME [city name] p [the number of neighbours of city NAME] nr cost [nr - index of a city connected to NAME (the index of the first city is 1)] [cost - the transportation cost] r [the number of paths to find <= 100] NAME1 NAME2 [NAME1 - source, NAME2 - destination] [empty line separating the tests]
Output
cost [the minimum transportation cost from city NAME1 to city NAME2 (one per line)]
Example
Input: 1 4 gdansk 2 2 1 3 3 bydgoszcz 3 1 1 3 1 4 4 torun 3 1 3 2 1 4 1 warszawa 2 2 4 3 1 2 gdansk warszawa bydgoszcz warszawa Output: 3 2
#pragma once #include <iostream> #include <stdio.h> #include <stdlib.h> #include <limits.h> #include <string> #include <map> using namespace std; class TheShortestPath15 { struct Node { int des, weight; Node *next; Node(int d, int w) : des(d), weight(w), next(NULL) {} }; struct AdjList { Node *head; AdjList() : head(NULL) {} }; struct Graph { int v; AdjList *arr; Graph(int v1) : v(v1) { arr = new AdjList[v]; } ~Graph() { for (int i = 0; i < v; i++) { Node *h = arr[i].head; while (h) { Node *next = h->next; delete h, h = NULL; h = next; } } delete arr, arr = NULL; } }; void addEdge(Graph *gra, int src, int des, int w) { Node *n = new Node(des, w); n->next = gra->arr[src].head; gra->arr[src].head = n; /* n = new Node(src, w); n->next = gra->arr[des].head; gra->arr[des].head = n; */ } struct HeapNode { int v, dist; explicit HeapNode(int v1, int d) : v(v1), dist(d) {} }; struct Heap { int size, cap; int *pos; HeapNode **arr; Heap(int c) : cap(c), size(0) { pos = new int[c]; arr = new HeapNode*[c]; } ~Heap() { delete [] pos, pos = NULL; for (int i = 0; i < size; i++) { if (arr[i]) delete arr[i], arr[i] = NULL; } delete [] arr; } }; void swapHeapNodes(HeapNode **a, HeapNode **b) { HeapNode *c = *a; *a = *b; *b = c; } void heapify(Heap *heap, int node) { if (!heap) return ; int minN = node; int left = (node<<1) + 1; int right = (node<<1) + 2; if (left < heap->size && heap->arr[left]->dist < heap->arr[minN]->dist) minN = left; if (right < heap->size && heap->arr[right]->dist < heap->arr[minN]->dist) minN = right; if (minN != node) { heap->pos[heap->arr[minN]->v] = node; heap->pos[heap->arr[node]->v] = minN; swapHeapNodes(&heap->arr[minN], &heap->arr[node]); heapify(heap, minN); } } inline bool isEmpty(Heap *heap) { return heap->size == 0; } HeapNode *extraMin(Heap *heap) { if (isEmpty(heap)) return NULL; HeapNode *root = heap->arr[0]; HeapNode *last = heap->arr[heap->size-1]; heap->arr[0] = last;//别漏了这步。 heap->pos[root->v] = heap->size-1; heap->pos[last->v] = 0; --heap->size; //别忘记先-- heapify(heap, 0); return root; } void decreaseKey(Heap *heap, int v, int dist) { int i = heap->pos[v]; heap->arr[i]->dist = dist; while (i && heap->arr[i]->dist < heap->arr[(i-1)>>1]->dist) { heap->pos[heap->arr[i]->v] = (i-1)>>1; heap->pos[heap->arr[(i-1)>>1]->v] = i; swapHeapNodes(&heap->arr[i], &heap->arr[(i-1)>>1]); i = (i-1)>>1; } } inline bool isInHeap(Heap *heap, int v) { return heap->pos[v] < heap->size; } void dijsktra(Graph *gra, int src, int des, int dist[]) { Heap *heap = new Heap(gra->v); heap->size = gra->v; for (int i = 0; i < gra->v; i++) { dist[i] = INT_MAX; heap->pos[i] = i; heap->arr[i] = new HeapNode(i, dist[i]); } dist[src] = 0; decreaseKey(heap, src, 0); while (!isEmpty(heap)) { HeapNode *hn = extraMin(heap); int u = hn->v; delete hn, hn = NULL; if (u == des) break; //这里增加代码,只找到目标节点就可返回了 if (dist[u] == INT_MAX) break; Node *n = gra->arr[u].head; while (n) { if (isInHeap(heap, n->des) && n->weight + dist[u] < dist[n->des]) { dist[n->des] = n->weight + dist[u]; decreaseKey(heap, n->des, dist[n->des]); } n = n->next; } } delete heap; } public: TheShortestPath15() { int s, n, p, nr, cost, r; map<string, int> cities; string name; scanf("%d", &s); while (s--) { scanf("%d", &n); Graph *gra = new Graph(n); for (int i = 0; i < n; i++) { //gets(NAME);教训:gets是取到\n或者EOF结束的,不是取单个单词 cin>>name; cities[name] = i; scanf("%d", &p); while (p--) { scanf("%d %d", &nr, &cost); addEdge(gra, i, nr-1, cost); } } scanf("%d", &r); while (r--) { cin>>name; int src = cities[name]; cin>>name; int des = cities[name]; int *dist = (int *) malloc(sizeof(int) * n); dijsktra(gra, src, des, dist); printf("%d\n", dist[des]); if (dist) free(dist); } delete gra; } } };
相关文章推荐
- SPOJ 15. The Shortest Path 最短路径题解
- 最短路径spoj15 The Shortest Path
- HDU 4725 The Shortest Path in Nya Graph(最短路径)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)
- codeforces-3A-Shortest path of the king( 棋盘最短路径 + 贪心 )
- SPOJ 15. The Shortest Path 堆优化Dijsktra
- SPOJ 15. The Shortest Path 堆优化Dijsktra
- 【codeforce Gym 100570B】【最短路SPFA】 ShortestPath Query 【询问单源最短路径,每条边有一个颜色,要求路径上相邻边的颜色不能相同】
- SPOJ-SHPATH - The Shortest Path
- GeeksForGeeks-Dijkstra’s shortest path algorithm最短路径
- Dijkstra's Shortest Path Algorithm(最短路径算法)
- 最短路径∷相关函数:ShortestPath_DIJ函数
- zoj 2760 How Many Shortest Path 【最短路 + 最大流】 【求边不重复最短路径条数】
- 最短路径算法—SPFA(Shortest Path Faster Algorithm)算法分析与实现(C/C++)
- Shortest path in multistage graphs 图的最短路径问题
- ZOJ 2760 How Many Shortest Path(最短路径+最大流)
- 最短路径算法—SPFA(Shortest Path Faster Algorithm)算法分析与实现
- 最短路径算法—SPFA(Shortest Path Faster Algorithm)算法分析与实现(C/C++)
- ZOJ 2760 How Many Shortest Path (不相交的最短路径个数)
- ZOJ 2760 How Many Shortest Path (不相交的最短路径个数)
- Codeforces 3A-Shortest path of the king(BFS打印路径)