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

使用堆优化Dijsktra的代码都是一大坨的。写起来好累。

要求对堆和图论和Dijsktra算法都十分熟悉。

这次写了两个多小时,最终过了,这种题目对思维锻炼是十分有帮助的。

优先熟悉堆的主要函数有:

1 堆中的元素添加和降低值的操作

2 取出堆顶值的操作

灵活修改Dijsktra。仅仅是求两点之间的最短路径。

之前使用指针写过。这次使用静态数组和vector来表示邻接表来解决。不用指针动态分配内存,速度更加快点。

Heap的操作所实用class封装起来了。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string>
#include <map>
#include <vector>
#include <string.h> using namespace std;
const int MAX_C = 15;
const int MAX_N = 10005; struct Node
{
int des, cost;
};
vector<Node> gra[MAX_N]; void insertNeighbor(int src, int des, int cost)
{
Node n;
n.cost = cost;
n.des = des;
gra[src].push_back(n);
} struct hNode
{
int ver, dis;
};
hNode heaps[MAX_N];
int hPos[MAX_N];//指示顶点在堆中的位置 class MinHeap
{
public:
int size;
MinHeap(int s = 0): size(s) {} int lson(int rt) { return rt<<1; }
int rson(int rt) { return rt<<1 | 1; }
int parent(int rt) { return rt>>1; } void swaphNode(int l, int r)
{
hNode t = heaps[l];
heaps[l] = heaps[r];
heaps[r] = t; hPos[heaps[r].ver] = r;
hPos[heaps[l].ver] = l;
} void pushUp(int rt)
{
while (parent(rt) > 0 && heaps[parent(rt)].dis > heaps[rt].dis)
{
swaphNode(rt, parent(rt));
rt = parent(rt);
}
} void pushDown(int rt)
{
int l = lson(rt);
if (l > size) return ;
int r = rson(rt); int sma = rt;
if (heaps[sma].dis > heaps[l].dis) sma = l;
if (r <= size && heaps[sma].dis > heaps[r].dis) sma = r; if (sma != rt)
{
swaphNode(sma, rt);
pushDown(sma);
}
} void increase(int ver, int dis)
{
int rt = hPos[ver];
heaps[rt].dis = dis; pushDown(rt);
} void decrease(int ver, int dis)
{
int rt = hPos[ver];
heaps[rt].dis = dis; pushUp(rt);
} void insert(int ver, int dis)
{
size++;
heaps[size].dis = dis;
heaps[size].ver = ver;
hPos[ver] = size; pushUp(size);
} bool verIsInHeap(int ver)
{
int rt = hPos[ver];
return rt <= size;
} bool isInHeap(int rt)
{
return rt <= size;
} void extractMin()
{
swaphNode(1, size);
--size;
pushDown(1);
}
}; int dijsktra(int src, int des, int vers)
{
MinHeap mheap;
for (int v = 1; v <= vers; v++)
{
mheap.insert(v, INT_MAX);
}
mheap.decrease(src, 0); for (int v = 1; v < vers; v++)
{
if (heaps[1].ver == des) return heaps[1].dis;
int u = heaps[1].ver;
int dis = heaps[1].dis; if (dis == INT_MAX) return INT_MAX;//防止溢出 mheap.extractMin(); int n = (int)gra[u].size();
for (int j = 0; j < n; j++)
{
int ver = gra[u][j].des;
int c = gra[u][j].cost;
int rt = hPos[ver]; if (mheap.isInHeap(rt) && dis+c < heaps[rt].dis)
{
mheap.decrease(ver, dis+c);
}
}
}
return heaps[1].dis;
} int main()
{
int T, n, p, nr, cost, r, src, des;
scanf("%d", &T);
while (T--)
{
scanf("%d", &n);
memset(heaps, 0, sizeof(hNode) * (n+1));
memset(hPos, 0, sizeof(int) * (n+1));
for (int i = 0; i <= n; i++)
{
gra[i].clear();
} map<string, int> msi;
char str[MAX_C];
for (int i = 1; i <= n; i++)
{
scanf("%s", str);
msi[str] = i;
scanf("%d", &p);
for (int j = 0; j < p; j++)
{
scanf("%d %d", &nr, &cost);
insertNeighbor(i, nr, cost);
}
}
scanf("%d", &r);
for (int i = 0; i < r; i++)
{
scanf("%s", str);
src = msi[str];
scanf("%s", str);
des = msi[str]; printf("%d\n", dijsktra(src, des, n));
}
}
return 0;
}

版权声明:笔者靖心脏,景空间地址:http://blog.csdn.net/kenden23/,只有经过作者同意转载。

SPOJ 15. The Shortest Path 堆优化Dijsktra的更多相关文章

  1. SPOJ 15. The Shortest Path 最短路径题解

    本题就是给出一组cities.然后以下会询问,两个cities之间的最短路径. 属于反复询问的问题,临时我仅仅想到使用Dijsktra+heap实现了. 由于本题反复查询次数也不多,故此假设保存全部最 ...

  2. [CF1051F]The Shortest Statement_堆优化dij_最短路树_倍增lca

    The Shortest Statement 题目链接:https://codeforces.com/contest/1051/problem/F 数据范围:略. 题解: 关于这个题,有一个重要的性质 ...

  3. POJ-2387.Til the Cows Come Home.(五种方法:Dijkstra + Dijkstra堆优化 + Bellman-Ford + SPFA + Floyd-Warshall)

    昨天刚学习完最短路的算法,今天开始练题发现我是真的菜呀,居然能忘记邻接表是怎么写的,真的是菜的真实...... 为了弥补自己的菜,我决定这道题我就要用五种办法写出,并在Dijkstra算法堆优化中另外 ...

  4. [CF843D]Dynamic Shortest Path

    [CF843D]Dynamic Shortest Path 题目大意: 给定一个带权有向图,包含\(n(n\le10^5)\)个点和\(m(m\le10^5)\)条边.共\(q(q\le2000)\) ...

  5. NEU 1685: All Pair Shortest Path

    题目描述 Bobo has a directed graph G with n vertex labeled by 1,2,3,..n. Let D(i,j) be the number of edg ...

  6. PAT-1030 Travel Plan (30 分) 最短路最小边权 堆优化dijkstra+DFS

    PAT 1030 最短路最小边权 堆优化dijkstra+DFS 1030 Travel Plan (30 分) A traveler's map gives the distances betwee ...

  7. Codeforces Round #303 (Div. 2) E. Paths and Trees Dijkstra堆优化+贪心(!!!)

    E. Paths and Trees time limit per test 3 seconds memory limit per test 256 megabytes input standard ...

  8. 深入理解dijkstra+堆优化

    深入理解dijkstra+堆优化 其实就这几种代码几种结构,记住了完全就可以举一反三,所以多记多练多优化多思考. Dijkstra   对于一个有向图或无向图,所有边权为正(边用邻接矩阵的形式给出), ...

  9. hdu-----(2807)The Shortest Path(矩阵+Floyd)

    The Shortest Path Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

随机推荐

  1. 分布式消息系统Jafka入门指南之二

    分布式消息系统Jafka入门指南之二 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 三.Jafka的文件夹结构 1.安装tree命令 $ sudo yu ...

  2. python学习笔记之十:文件和素材

    这里将介绍函数和对象--文件和流,让你在程序调用期间存储数据,并且可以处理来自其他程序的数据. 一. 打开文件 1.1 open函数 open函数用来打开文件,语法如下:open(name,[.mod ...

  3. SecureCRT 6.7.1 注冊机 和谐 破解 补丁 方法

    之前一直在用SecureCRT 6.5.3 版本号,和谐补丁也好找,甚至中文版本号也可找到(眼下仅仅找到了SecureCRT.6.2.0) 可是换为 6.7.1 后就怎么也注冊不了了.. 没办法试了各 ...

  4. Dreamer 3.0 支持json、xml、文件上传

    自己写的框架,功能类似Struts2.x 下载地址:http://pan.baidu.com/share/link?shareid=3273223286&uk=470382596 新增功能: ...

  5. hadoop调度程序时出现“Error opening job jar”错误

    提示出现的问题: Exception in thread "main" java.io.IOException: Error opening job jar: /home/depl ...

  6. Excel阅读器NPOI

    什么是NPOI? NPOI 它是 POI 项目的 .NET 版本号. POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 使用 NPOI 你就能够在没有安装 Office ...

  7. Oracle数据库的锁类型

    Oracle数据库的锁类型 博客分类: oracle   Oracle数据库的锁类型 根据保护的对象不同,Oracle数据库锁可以分为以下几大类:DML锁(data   locks,数据锁),用于保护 ...

  8. Red Gate系列之五 .NET Reflector 7.6.1.824 Edition .NET程序反编译神器(附插件安装教程2012-10-13更新) 完全破解+使用教程

    原文:Red Gate系列之五 .NET Reflector 7.6.1.824 Edition .NET程序反编译神器(附插件安装教程2012-10-13更新) 完全破解+使用教程 Red Gate ...

  9. 全文检索引擎Solr 指南

    全文检索引擎Solr系列:第一篇:http://t.cn/RP004gl.第二篇:http://t.cn/RPHDjk7 .第三篇:http://t.cn/RPuJt3T

  10. 聊聊并发(六)——ConcurrentLinkedQueue的实现原理分析

    1. 引言 在并发编程中我们有时候需要使用线程安全的队列.如果我们要实现一个线程安全的队列有两种实现方式:一种是使用阻塞算法,另一种是使用非阻塞算法.使用阻塞算法的队列可以用一个锁(入队和出队用同一把 ...