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

    FluentData微型ORM 最近在帮朋友做一个简单管理系统,因为笔者够懒,但是使用过的NHibernate用来做这中项目又太不实际了,索性百度了微型ORM,FluentData是第一个跳入我眼睛的 ...

  2. 用C++语言开发Android程序 配置开发环境

    转自:http://www.cnblogs.com/yaotong/p/3622430.html 用C++语言开发Android程序 配置开发环境   如果你是一个C++语言的死忠,你喜欢C++语言到 ...

  3. Maven插件之git-commit-id-plugin

    SCM使用GIT而非SVN时,使用Maven发布,总是会出一些莫名其妙的问题,google查找原因,无意中看到了这个插件; 对于该插件,到目前为止,文档比较少,尤其是中文的文档;全部的信息都包含在项目 ...

  4. HTML中&lt;input&gt;參数,以及文本输入框,文本域的解说

    <form> <input type="text/password" name="名称" value="文本" /> ...

  5. 通过 HTTP 头进行 SQL 注入(转)

    英文原文:DatabaseTube,翻译:开源中国 在漏洞评估和渗透测试中,确定目标应用程序的输入向量是第一步.这篇文章解释了别人是如何通过HTTP头部对你的数据库进行SQL注入攻击的,以及讨论下选择 ...

  6. 详细分析Java中断机制(转)

    1. 引言 当我们点击某个杀毒软件的取消按钮来停止查杀病毒时,当我们在控制台敲入quit命令以结束某个后台服务时……都需要通过一个线程去取消另一个线程正在执行的任务.Java没有提供一种安全直接的方法 ...

  7. 开源Office Word——DocX

    1.前言 请阅读前请看以下这位大神的文章 http://www.cnblogs.com/asxinyu/archive/2013/02/22/2921861.html 另附两个附件 1.DocX.DL ...

  8. android升级软件版本号,您安装后的新版本号,成功安装画面没有出现,或直接回到桌面

    Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //an ...

  9. Nagios监控生产环境redis群集服务战

    前言:     曾经做了cacti上展示redis性能报表图.能够看到redis的性能变化趋势图,可是还缺了实时报警通知的功能,如今补上这一环节. 在redis服务瓶颈或者异常时候即使报警通知,方便d ...

  10. [Windows Phone] 导览控制项(Navigation controls)

    原文:[Windows Phone] 导览控制项(Navigation controls) [前言] 如果应用程式只有单一页面,在画面呈现上可能会让使用者容易没有新鲜感,这个范例是使用导览控制项(Na ...