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 ...
随机推荐
- SVG 浏览器支持
可以参考以下链接: https://caniuse.com/#search=svg https://en.wikipedia.org/wiki/Comparison_of_layout_engines ...
- TCP的链接过程
** TCP 三次握手 四次挥手** 客户端 服务器端 交互的模式 ---> 应答模式* 应答模式 ---> 客户端发起请求 服务器端回应请求** 客户端先去发起请求 ---> 查看 ...
- 2019浙师大校赛(浙大命题)(upc复现赛)总结
2019浙师大校赛(浙大命题)(upc复现赛)总结 早上九点开始.起得迟了,吃了早饭慌慌张张跑过去,刚到比赛就开始了. 开始分别从前往后和从后往前看题,一开始A题,第一发WA,第二次读题发现漏看了还有 ...
- 启发式合并 CodeForces - 600E
启发式合并最重要的思想就是指的是每次将小集合拷贝合并至大集合.考虑每个元素的合并开销.对于合并次数最多的那个元素来说,它每合并一次,所在集合的规模扩大两倍,最多只会合并 logN 次,因而对于所有元素 ...
- mysql崩溃恢复
mysql进程崩溃. 杀掉所有mysql进程,在my.cnf文件中写入innodb_recover_force=1,强制并忽略任何错误启动数据库. 用mysqldump导出所有数据,在新机器上部署好m ...
- 4.model 字段
一.字段名 字段名 类型 参数 AutoField(Field) - int自增列, 必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自 ...
- ajax 简单学习
客户端代码function login(type) { $.ajax({ type: "post", url: "logindo.aspx", data: { ...
- 自媒体人Chrome浏览器必备插件精选神器!
自从互联网时代起,浏览器使用从最早的IE,到opera,到猎豹浏览器,到360双核浏览器,到火狐,到safari,到目前最喜欢用的chrome.一路下来,chrome的稳定性与扩展性征服了我,成了我必 ...
- pycharm中提交Git 忽略部分代码
痛点: 项目中,有些配置项,或者比较隐私的东东,不想上传 解决:在项目根路径下,创建.gitignore 文件 文件中可以写文件名.文件路径等 结果: 提交到git,发现果真没有dbconne ...
- 经典卷积网络VGG,GoodLeNet,Inception
目录 ImageNet LeNet-5 LeNet-5 Demo AlexNet VGG 1*1 Convolution GoogLeNet Stack more layers? ImageNet L ...