POJ-1724 Roads + Python (DFS)

原题链接:1724 -- ROADS

参考资料:王子解救公主力扣 174. 地下城游戏 DFS + Python_xxdragon126的博客-CSDN博客

一 问题描述:

从起始城市1到终止城市N,要求在路费ALL可控的情况下路程最短,返回最短路程。详见原题链接。

解题思路:

## 使用DFS:

# 1 首先,将数据转化为嵌套的字典,以便于查找当前城市所能到达的所有邻接城市,以及到达各邻接城市所需的路程和路费。

# 2 然后,从起始点1开始,查找其邻接点城市,将每个邻接点城市作为初始点,进行dfs搜索

# 2.1 如果子节点(邻接点)已经访问过,则不再访问,返回

# 2.2 如果到达目标城市:

        # 2.2.1 如果当前路费总和不超支:

                # 2.2.1.1 如果当前路程总数更小

                # 2.2.1.2 则更新当前方案及路程数

# 2.3 否则,进行dfs循环,去查找当前节点的子节点

三 代码实现

# POJ-1724 Roads.py
# http://poj.org/problem?id=1724


## 使用DFS:
# 1 首先,将数据转化为嵌套的字典,以便于查找当前城市所能到达的所有城市,以及到达各城市所需的路径和路费
# 2 然后,从起始点1开始,查找其邻接点城市,将每个邻接点城市作为初始点,进行dfs搜索
# 2.1 如果子节点(邻接点)已经访问过,则不再访问,返回
# 2.2 如果到达目标城市:
# 2.2.1 如果当前路费总和不超支:
# 2.2.1.1 如果当前路程总数更小
# 2.2.1.2 则更新当前方案及路程数
# 2.3 否则,进行dfs循环,去查找当前节点的子节点

# 本题跟王子救公主题目的思路比较相似

import collections
import math
## DFS处理
class Solution:
    def DFS(self):
        ###
        start_node = graph[start].keys()
        self.ways = [] # 存储最终方案
        ###
        ## 对每一个节点进行处理
        for node in start_node:
            # 设置初始的总路径
            self.Path = math.inf
            ## 设置访问列表
            ## 将初始节点添加进来
            queue = [start]
            # 父节点为
            pre_node = start
            # 路费之和
            cost_sum = 0
            # 路径之和
            path_sum = 0
            ## 循环
            self.dfs(pre_node,node,queue,cost_sum,path_sum)
        return self.Path

    def dfs(self,pre_node,node,queue,cost_sum,path_sum):
        ## 判断当前节点是否已经访问过
        if node in queue:
            return
        ## 如果未曾访问过则继续
        ## 传递数据
        new_queue = []
        new_queue.append(node)
        for i in queue:
            new_queue.append(i)
        new_queue.append(node)
        new_queue.pop(0)
        ## 判断节点是否为目标点
        if node == target:
            ## 判断有没有超过所需钱数
            if graph[pre_node][node][1] + cost_sum <= ALL:
                ## 判断路径之和是否更小
                if graph[pre_node][node][0] + path_sum < self.Path:
                    # 更新方案
                    self.ways = new_queue
                    self.Path = graph[pre_node][node][0] + path_sum
                    return
        ## 如果没有到达目标节点:则查找当前节点的下一步的节点
        new_nodes = graph[node]
        ### 对每个节点进行分析
        for new_node in new_nodes:
            # 添加入访问列表
            if new_node not in new_queue:
                 self.dfs(node,new_node,new_queue,graph[pre_node][node][1] + cost_sum,graph[pre_node][node][0] + path_sum)
        ## 如果没有可行方案,则返回吧
        return
#####
# 数据转换一下,转成嵌套的索引形式
def sub2graph(grapg):
    dataGrapg = collections.defaultdict(list)
    for key in grapg.keys():
        temp = grapg[key]
        temp_dict = {}
        for i in range(len(temp)):
            temp_dict[temp[i][0]] = temp[i][1:]
            # temp_dict.update()
        dataGrapg[key] = temp_dict
    return dataGrapg

## 迎接数据
ALL = int(input()); #总钱数
N = int(input());# 总城市数
nRode = int(input());# 总路径数

data = []
grapg = collections.defaultdict(list)
for i in range(nRode):
    temp = list(map(int,input().strip().split(' ')))
    grapg[temp[0]].append(temp[1:])
# print(grapg)

## 开始处理
start = 1;# 初始节点
target = N;#目标节点

graph = sub2graph(grapg)#转化为嵌套字典
test = Solution()
ans = test.DFS()
if ans!= math.inf:
    print(ans)
else:
    print('-1')


第二版:

import collections
import math

## 
# 迎接数据
All = int(input().strip())
target = int(input().strip())
N = int(input().strip())
# print(All,target,N)
data_dict = collections.defaultdict(list)
for i in range(N):
    temp = list(map(int,input().strip().split(' ')))
    data_dict[temp[0]].append(temp[1::])
#print(data_dict)
##
# 数据处理
def sub2dict(data_dict):
    new_dict = collections.defaultdict(list)
    keys = data_dict.keys()
    for key in keys:
        temp_data = data_dict[key]
        temp_dict = collections.defaultdict(list)
        for i in temp_data:
            temp_dict[i[0]] = i[1::]
        new_dict[key] = temp_dict
    return new_dict

new_dict = sub2dict(data_dict)
#print(new_dict)

##
class Solutions:
    def DFS(self):
        start = 1;
        self.Path = []
        start_nodes = new_dict[start].keys()
        for node in start_nodes:
            pre_node = start
            queue = [pre_node]
            #
            self.path = math.inf
            #
            sum_len = 0
            sum_cost = 0
            self.dfs(pre_node,node,sum_len,sum_cost,queue)
            self.Path.append(self.path)
        return min(self.Path)
    def dfs(self,pre_node,node,sum_len,sum_cost,queue):
        ## 判断是否已经存在
        if node in queue:
            return
        ## 判断是否超过钱数
        if sum_cost + new_dict[pre_node][node][1] > All:
            return 
        ## 判断是否等于目标
        if node == target:
            ## 判断是否为更小的路径
            if sum_len + new_dict[pre_node][node][0]

输入:

5
6
7
1 2 2 3
2 4 3 3
3 4 2 4
1 3 4 1
4 6 2 1
3 5 2 0
5 4 3 2

输出:

11

POJ-1724 Roads + Python (DFS)_第1张图片

你可能感兴趣的:(刷题,深度优先,python,图论)