本题就是给出一组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 最短路径题解的更多相关文章

  1. SPOJ 15. The Shortest Path 堆优化Dijsktra

    You are given a list of cities. Each direct connection between two cities has its transportation cos ...

  2. [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 ...

  3. 最短路径遍历所有的节点 Shortest Path Visiting All Nodes

    2018-10-06 22:04:38 问题描述: 问题求解: 本题要求是求遍历所有节点的最短路径,由于本题中是没有要求一个节点只能访问一次的,也就是说可以访问一个节点多次,但是如果表征两次节点状态呢 ...

  4. ZOJ 2760 How Many Shortest Path(最短路径+最大流)

    Description Given a weighted directed graph, we define the shortest path as the path who has the sma ...

  5. 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 ...

  6. 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 ...

  7. 程序员的算法课(19)-常用的图算法:最短路径(Shortest Path)

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  8. [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 ...

  9. 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 ...

随机推荐

  1. RestTemplate接收HashMap变为LinkedHashMap,RestTemplate接收数据后转成json数据出现反斜杠

    使用postForObject方法远程调用接口,正常会返回List<HashMap>,然而实际上却返回List<LinkedHashMap>,同时将此数据进行json转换,变成 ...

  2. 第2节 mapreduce深入学习:11、maptask运行机制(多看几遍)

    mapTask运行机制详解以及mapTask的并行度在mapTask当中,一个文件的切片大小使用默认值是128M,就是跟我们一个block块对应大小一样 MapTask运行的整个过程 背下来1.Tex ...

  3. formatDate() 格式化日期

    function datefmt(milSec, format) { var oldTime = Number(milSec); //得到毫秒数 // 日期格式转换 var t = new Date( ...

  4. Ztree勾选节点后取消勾选其父子节点

    前言: Ztree官方给的API可以设置勾选一个节点的同时勾选子节点或者父节点,也可以设置不影响父子节点,即将chkboxType设置为{"Y":"",&quo ...

  5. js ajax 传送xml dom对象到服务器

    客户端代码 1 <script> var isie = true; var xmlhttp = null; function createXMLHTTP() {//创建XMLXMLHttp ...

  6. Python之文件处理-递归删除特定文件

    Python之文件处理-递归删除特定文件 #!/usr/bin/env python # -*- coding:utf-8 -*- import os def delete_particular_fi ...

  7. windows下mysql 5.7版本中修改编码为utf-8的方法

    方法如下 首先通过 show variables like 'character_set_%';查看mysql字符集情 默认编码为 latin1 然后关闭数据库 在mysql安装目录下找到my.ini ...

  8. 【转载】什么是Zero-Copy

    转载:https://blog.csdn.net/u013256816/article/details/52589524 概述 考虑这样一种常用的情形:你需要将静态内容(类似图片.文件)展示给用户.那 ...

  9. 怎样判断有没有SQL注入?

    最为经典的单引号判断法: 在参数后面加上单引号,比如: http://xxx/abc.php?id=1' 如果页面返回错误,则存在 Sql 注入. 原因是无论字符型还是整型都会因为单引号个数不匹配而报 ...

  10. 牛客网sql练习

    一建表语句 /* Navicat MySQL Data Transfer Source Server : test Source Server Version : 50717 Source Host ...