SPOJ 15. The Shortest Path 最短路径题解
本题就是给出一组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.
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 最短路径题解的更多相关文章
- SPOJ 15. The Shortest Path 堆优化Dijsktra
You are given a list of cities. Each direct connection between two cities has its transportation cos ...
- [Swift]LeetCode847. 访问所有节点的最短路径 | Shortest Path Visiting All Nodes
An undirected, connected graph of N nodes (labeled 0, 1, 2, ..., N-1) is given as graph. graph.lengt ...
- 最短路径遍历所有的节点 Shortest Path Visiting All Nodes
2018-10-06 22:04:38 问题描述: 问题求解: 本题要求是求遍历所有节点的最短路径,由于本题中是没有要求一个节点只能访问一次的,也就是说可以访问一个节点多次,但是如果表征两次节点状态呢 ...
- ZOJ 2760 How Many Shortest Path(最短路径+最大流)
Description Given a weighted directed graph, we define the shortest path as the path who has the sma ...
- AOJ GRL_1_C: All Pairs Shortest Path (Floyd-Warshall算法求任意两点间的最短路径)(Bellman-Ford算法判断负圈)
题目链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_C All Pairs Shortest Path Input ...
- AOJ GRL_1_B: Shortest Path - Single Source Shortest Path (Negative Edges) (Bellman-Frod算法求负圈和单源最短路径)
题目链接: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_1_B Single Source Shortest Path ...
- 程序员的算法课(19)-常用的图算法:最短路径(Shortest Path)
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...
- [LeetCode] 847. Shortest Path Visiting All Nodes 访问所有结点的最短路径
An undirected, connected graph of N nodes (labeled 0, 1, 2, ..., N-1) is given as graph. graph.lengt ...
- HDU 4725 The Shortest Path in Nya Graph(最短路径)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)
Description This is a very easy problem, your task is just calculate el camino mas corto en un grafi ...
随机推荐
- CAD参数绘制实心圆弧填充(com接口)
C#中实现代码说明: private void DrawPathToHatch1() { //把路径的开始位置移动指定的点 //参数一为点的X坐标 ,参数二为点的Y坐标,参数三为该点处开始宽度,对Po ...
- Mac OS X 中安装 brew
不想被误导?直接看官方文档: http://mxcl.github.com/homebrew/ 先安装Git,打开一个shell cd /usr/local sudo mkdir homeb ...
- No-5.变量的命名
变量的命名 目标 标识符和关键字 变量的命名规则 0.1 标识符和关键字 1.1 标识符 标示符就是程序员定义的 变量名.函数名 名字 需要有 见名知义 的效果 标示符可以由 字母.下划线 和 数字 ...
- 第3节 mapreduce高级:12、mapreduce相关的参数调整
5.1 多job串联 一个稍复杂点的处理逻辑往往需要多个mapreduce程序串联处理,多job的串联可以借助mapreduce框架的JobControl实现 示例代码: ControlledJob ...
- hdfs深入:05、hdfs中的fsimage和edits的合并过程
6.4.secondarynameNode如何辅助管理FSImage与Edits文件 ①:secnonaryNN通知NameNode切换editlog ②:secondaryNN从NameNode中获 ...
- C# Word 类库
C# Word 类库 2009-08-06 22:10 14292人阅读 评论(11) 收藏 举报 c#objectstring文档microsoftexcel using System;using ...
- js文字内容部分选中的代码封装
var textSelect = function(o, a, b){ //o是当前对象,例如文本域对象 //a是起始位置,b是终点位置 var a = parseInt(a, 10), b = pa ...
- 笔试算法题(56):快速排序实现之非递归实现,最小k值选择(non-recursive version, Minimal Kth Selection of Quick Sort)
议题:快速排序实现之五(非递归实现,短序列优先处理,减少递归栈大小) 分析: 算法原理:此算法实现适用于系统栈空间不足够快速排序递归调用的需求,从而使用非递归实现快速排序算法:使用显示下推栈存储快速排 ...
- sql server 备份计划
SSMS 1.管理 2.维护计划 3.维护计划向导 或者 1. server 代理 2. 作业 3. 新建作业 备份计划时间尽量选在闲时, 例如午夜
- Atcoder regular Contest 073(C - Sentou)
Atcoder regular Contest 073(C - Sentou) 传送门 每个人对开关的影响区间为a[i]--a[i]+t,因此此题即为将所有区间离散化后求所有独立区间的长度和 #inc ...