python使用 Dijkstra算法解决--温差最小路径问题
程序员文章站
2022-03-14 21:21:58
问题描述一些村庄由许多条小路连接,由于每条小路处于不同的地理位置,因此每条小路上的温度是不一样的。村民们要前往另一村庄时,对这条路径的绝对温度没有要求,但若一条路径的最大温度与最低温度之间的温差过大,会导致感冒。请你找出两个村庄间的温差最小的路径。输入第一行是一个正整数q,表示测试例数量。对每个测试例第一行有2个整数n(1
问题描述
一些村庄由许多条小路连接,由于每条小路处于不同的地理位置,因此每条小路上的温度是不一样的。村民们要前往另一村庄时,对这条路径的绝对温度没有要求,但若一条路径的最大温度与最低温度之间的温差过大,会导致感冒。
请你找出两个村庄间的温差最小的路径。
输入
- 第一行是一个正整数q,表示测试例数量。
- 对每个测试例
第一行有2个整数n(1<n≤400)和m(m≤2000),表示有n个村庄和m条小路。
接下来m行都是3个正整数,分别是小路起始村庄号,小路终止村庄号,小路上的温度T(T≤2000000)。
然后有一个正整数P(P≤10),表示寻路次数。
接下来P行,每行有2个正整数,分别表示村民的起始村庄号,村民的目的村庄号。
输出
每个寻路打印一行,表示温差最小的温差,若不能到达,输出-1.
输入样例
1
5 5
1 2 2
1 5 6
2 5 7
3 4 4
3 5 8
2
1 3
1 2
输出结果
2
0
解题思路
代码实现
#!/usr/bin/env python3
#temperature.py
#fumiama 20201120
from heapq import heappop, heappush, heapify
class UnionFindSet(object):
def __init__(self, nodes):
self.fatherMap = {}
self.setNumMap = {}
for node in nodes:
self.fatherMap[node] = node
self.setNumMap[node] = 1
def findFather(self, node):
father = self.fatherMap[node]
if (node != father):
father = self.findFather(father)
self.fatherMap[node] = father
return father
def isSameSet(self, a, b):
return self.findFather(a) == self.findFather(b)
def union(self, a, b):
if a is None or b is None: return
aFather = self.findFather(a)
bFather = self.findFather(b)
if (aFather != bFather):
aNum = self.setNumMap[aFather]
bNum = self.setNumMap[bFather]
if (aNum <= bNum):
self.fatherMap[aFather] = bFather
self.setNumMap[bFather] = aNum + bNum
self.setNumMap.pop(aFather)
else:
self.fatherMap[bFather] = aFather
self.setNumMap[aFather] = aNum + bNum
self.setNumMap.pop(bFather)
class Node(object):
def __init__(self, name):
self.name = name
self.distance = 0
self.path = [name]
self.maxT = -1
self.minT = 2000001
def __repr__(self):
return "号节点" + ", 最短路径花费"+ str(self.distance)+ ": " + str(self.path) + '\n'
def setNode(self, preNode, tempDiff):
self.distance = tempDiff
self.path = preNode.path[:]
self.path.append(self.name)
def getNewTempDiff(self, temp):
minT = self.minT
maxT = self.maxT
return (temp if temp > maxT else maxT) - (temp if temp < minT else minT)
def setStartTemp(self, temp): self.maxT = self.minT = temp
class Graph(object):
def __init__(self, nodeCnt):
self.nodes = dict()
self.node2edge = dict()
self._node2edge = dict()
self.nodeNames = set()
self.nodeCnt = nodeCnt
def __repr__(self):
return "图共有" + str(self.nodeCnt) + "个节点如下:\n " + str(self.nodes)
def addEdge(self, start, end, weight): #无向图
self._addEdge(start, end, weight)
self._addEdge(end, start, weight)
def _addEdge(self, start, end, weight): #有向图
if start not in self.nodes.keys(): self.nodes[start] = Node(start)
newEdge = (weight, end)
if start not in self.node2edge.keys():
self.node2edge[start] = {newEdge}
self._node2edge[start] = {newEdge}
else:
self.node2edge[start].add(newEdge)
self._node2edge[start].add(newEdge)
if start not in self.nodeNames: self.nodeNames.add(start)
if end not in self.nodeNames: self.nodeNames.add(end)
def resetNode2Edge(self): self.node2edge = self._node2edge.copy()
def getMinTempDiff(self, start, end):
wedge = []
for e in self.node2edge[start]:
wedge.append((0, start, e[1]))
self.nodes[e[1]].setStartTemp(e[0])
self.node2edge[e[1]].remove((e[0], start))
self.node2edge[start] = set()
forest = UnionFindSet(self.nodeNames)
result = -1
while wedge:
#print("带权边界边:", wedge)
minEdge = heappop(wedge)
thisNode = self.nodes[minEdge[1]]
nextNode = self.nodes[minEdge[2]]
if not forest.isSameSet(thisNode.name, nextNode.name):
nextNode.setNode(thisNode, minEdge[0])
if nextNode.name == end:
result = nextNode.distance
break
edgesOfNextNode = self.node2edge[nextNode.name]
while edgesOfNextNode:
edge = edgesOfNextNode.pop()
self.node2edge[edge[1]].remove((edge[0], nextNode.name))
heappush(wedge, (nextNode.getNewTempDiff(edge[0]), nextNode.name, edge[1]))
forest.union(thisNode.name, nextNode.name)
return result
if __name__ == '__main__':
q = int(input())
while q:
n, m = map(int, input().split())
g = Graph(n)
while m:
a, b, t = map(int, input().split())
g.addEdge(a, b, t)
m -= 1
p = int(input())
while p:
a, b = map(int, input().split())
print(g.getMinTempDiff(a, b))
g.resetNode2Edge()
p -= 1
q -= 1
本文地址:https://blog.csdn.net/u011570312/article/details/110289786
上一篇: element ui 实现动态改变面包屑
推荐阅读
-
Python数据结构与算法之使用队列解决小猫钓鱼问题
-
Python使用Dijkstra算法实现求解图中最短路径距离问题详解
-
python实现Dijkstra算法的最短路径问题
-
python使用 Dijkstra算法解决--温差最小路径问题
-
Python使用遗传算法解决最大流问题
-
【量化交易】SciPy-Python科学算法库安装、附带切换python版本、及python虚拟环境路径问题解决。
-
Python使用Dijkstra算法实现求解图中最短路径距离问题详解
-
python实现Dijkstra算法的最短路径问题
-
使用Dijkstra/Floyd算法解决最短路径问题
-
Python数据结构与算法之使用队列解决小猫钓鱼问题