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 ...
随机推荐
- (function(){})() 立即执行函数
(function(){})() 立即执行函数 (function(a){})(5) 带参的
- JavaScript 原生代码找对象的方法
1. id : document.getElementById('id') 2. 标签 : document.getElementsByTagName('标签') //获得的是一个标签数组 3. N ...
- TCP/IP 协议分层
协议分层 可能大家对OSI七层模型并不陌生,它将网络协议很细致地从逻辑上分为了7层.但是实际运用中并不是按七层模型,一般大家都只使用5层模型.如下: 物理层:一般包括物理媒介,电信号,光信号等,主要对 ...
- CAD嵌套打印(com接口版)
当用户需要打印两个CAD控件的图纸时,可以采用嵌套打印实现.实现嵌套打印功能,首先将两个CAD控件放入网页中,C#代码如下: private void BatchPrintDialog() { MxD ...
- 08JavaScript数学与日期时间对象
JavaScript数学与日期时间对象 5.1.3数学(Math)对象 <script> //欧拉常量,自然对数的底(约等于2.718); document.write(Math.E+&q ...
- JavaSE-10 多态
学习要点 多态的优势和应用场合 父类和子类之间的类型转换 instanceof运算符的使用 父类作为方法形参实现多态 父类作为返回值实现多态 使用多态的原因 需求描述: 在宠物管理系统中,宠物饿了,需 ...
- bash基础——管道符、通配符
1.多命令顺序执行 多命令顺序执行 格式 作用 ; 命令1 ; 命令2 多个命令之间没有任何逻辑联系 && 命令1&&命令2 逻辑与 当命令1正确执行,则命令2才会执行 ...
- 基于js插件的文件上传
<?php /** * Created by PhpStorm. * User: GyCCo. * Date: 05/02/2018 * Time: 4:46 PM */ session_sta ...
- python在linux下的使用
1.查看python(解释器)的版本(什么版本的解释器支持哪一版版的语言标准) 一般在linux上已经预装了python,只要在Bash Shell中输入python,即可看到如下版本信息: 按Ctr ...
- 笔试算法题(14):整数二进制表示中的1 & 判定栈的push和pop序列是否对应
出题:输入一个整数,要求计算此整数的二进制表示中1的个数 分析: 如果整数表示为k,当其是负数的时候,使用1<<i分别检测k的每一位:当其位整数的时候,则k/2表示将其二进制表示右移一位, ...