本题就是给出一组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. 10CSS高级滤镜

    CSS高级滤镜 滤镜特效的应用    filter:滤镜属性(参数1,参数2,……) filter是滤镜属性选择符. 透明度——alpha opacity代表透明度等级,参数值从0到100,从完全透明 ...

  2. js模拟输入支付密码

    html <div class="content"> <!--<div class="title">支付宝支付密码:</di ...

  3. Spring Data Redis入门示例:Hash操作(七)

    将对象存为Redis中的hash类型,可以有两种方式,将每个对象实例作为一个hash进行存储,则实例的每个属性作为hash的field:同种类型的对象实例存储为一个hash,每个实例分配一个field ...

  4. svn in xcode5

    两种办法,一是使用比较成熟的svn客户端,二是使用终端.以下为终端方法: 假设已经通过Xcode->Preferences->Accounts将repository: http://mys ...

  5. CSU1019: Simple Line Editor

    1019: Simple Line Editor Submit Page   Summary   Time Limit: 1 Sec     Memory Limit: 128 Mb     Subm ...

  6. CSU1018: Avatar

    1018: Avatar Submit Page   Summary   Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: 841   ...

  7. Linux命令学习(5):more和less

    引子 平常工作中经常需要查看很大的文本文件,如果用vi打开的话会非常慢,所以平常都用less,但是并没有很系统地学习过less的用法,今天总结一下less和more的用法. 经过学习我发现less比m ...

  8. NodeJs中数据库的使用

    另一遍通用的NODEJS数据库方法koa,express,node 通用方法连接MySQL 1.Node.js 连接 MySQL $ cnpm install mysql 连接mysql: var m ...

  9. LeetCode(46)Permutations

    题目 Given a collection of numbers, return all possible permutations. For example, [1,2,3] have the fo ...

  10. 有趣的鼠标悬浮模糊效果总结---(filter,渐变文字)

    绘制渐变背景图 第一种:大神的想法,摘抄 background-image: -webkit-linear-gradient(left, blue, red 25%, blue 50%, red 75 ...