tasks for today:
1. Floyd 算法 97.小明逛公园
2. A* 算法 126.骑士的攻击
-------------------------------------------------------------------------------
1. Floyd 算法 97.小明逛公园
This practice has multiple staring points, aiming to find the most efficient starting point. A new algorithm is introduced - Floyd, which is suitable for both cases having or not having negative edges. This algorithm is based on mindset of dynamic programming.
in this pratice, here are some points needed to be noted.
(1) the meaning of dp matrix which is grid in following code, a 3-dim matrix.
(2) the initialization of grid necessitates one more place for each dimention which represents a dummy node as node 0 for the convience of the following operation on other nodes from node 1 to node n.
(3) each entry of grid matrix grid[i][j][k], that means the minimum distance from node i to node j by using the points from 1 to k.
(4) the reaverse sequences of each dimension, k should be in the outer loop due to the recusive equation's calculation in each step.
def main():
n, m = map(int, input().split())
grid = [[[10005] * (n+1) for _ in range(n+1)] for _ in range(n+1)]
for _ in range(m):
u, v, w = map(int, input().split())
grid[u][v][0] = w
grid[v][u][0] = w
for k in range(1, n+1):
for i in range(1, n+1):
for j in range(1, n+1):
grid[i][j][k] = min(grid[i][j][k-1], grid[i][k][k-1]+grid[k][j][k-1])
Q = int(input())
for _ in range(Q):
start, end = map(int, input().split())
if grid[start][end][n] == 10005:
print(-1)
else:
print(grid[start][end][n])
return
if __name__ == "__main__":
main()
2. A* 算法 126.骑士的攻击
A* algorithm is actually an upgraded algorithm based on the BFS(for non-weighted graph) or dijkstra(for weighted graph), through a usage of heuristic rules when retrieving the searching points from the queue or heap.
import heapq
directions = [[2,1],[2,-1],[-2,1],[-2,-1],[1,2],[1,-2],[-1,2],[-1,-2]]
class Node:
def __init__(self):
self.x = 0
self.y = 0
self.f = 0
self.g = 0
self.h = 0
# this is for the usage of the heapq, when the f is the same
def __lt__(self, other):
return self.f < other.f # This allows direct comparison based on `f`
def distance(node, b1, b2):
return (node.x - b1) ** 2 + (node.y - b2) ** 2
def astar(start, b1, b2, move):
curQueue = []
heapq.heappush(curQueue, (start.f, start))
while curQueue:
curF, curNode = heapq.heappop(curQueue)
if curNode.x == b1 and curNode.y == b2:
break
for direc in directions:
nextNode = Node()
nextNode.x = curNode.x + direc[0]
nextNode.y = curNode.y + direc[1]
if nextNode.x < 0 or nextNode.x > 1000 or nextNode.y < 0 or nextNode.y > 1000:
continue
if move[nextNode.x][nextNode.y] == 0:
move[nextNode.x][nextNode.y] = move[curNode.x][curNode.y] + 1
nextNode.g = curNode.g + 5
nextNode.h = distance(nextNode, b1, b2)
nextNode.f = nextNode.g + nextNode.h
heapq.heappush(curQueue, (nextNode.f, nextNode))
def main():
n = int(input())
for _ in range(n):
move = [[0] * 1001 for _ in range(1001)]
a1, a2, b1, b2 = map(int, input().split())
# print(a1,a2,b1,b2)
start = Node()
start.x = a1
start.y = a2
start.g = 0
start.h = distance(start, b1, b2)
start.f = start.g + start.h
astar(start, b1, b2, move)
print(move[b1][b2])
return
if __name__ == "__main__":
main()