首页 > 其他分享 >OD C卷 - 快递员的烦恼

OD C卷 - 快递员的烦恼

时间:2024-03-23 16:59:46浏览次数:32  
标签:distance matrix cid OD 烦恼 投递 快递 客户 id

快递员的烦恼(200)

  • 保证快递送到客户手中,不限制先后顺序;
  • 所有快递送完后,快递员还需要回到投递站(只有一个);
  • 投递站与客户之间都有路线,但客户与客户之间不一定有路线;投递站、客户位置均允许多次经过;
    输入描述:
    首行输入两个正整数n, m;
    下面n行,输入快递信息,格式为 客户id 投递站到该客户的距离distance
    最后m行,是快递员自行查找的客户与客户之间的距离,格式为:客户1id, 客户2id, distance
    0<n<=10
    0<= m <=10
    0<客户id<=1000
    0<distance<=10000
    输出描述:
    最短路径的距离,若无法找到,输出-1

示例1
输入:
2 1
1 1000
2 1200
1 2 300
输出:
2500
说明:
路径1,投递站-客户1-客户2-投递站 2500
路径2,投递站-客户2-客户1-投递站 2500
路径3,投递站-客户1-投递站-客户2-投递站4400

示例2:
输入:
5 1
5 1000
9 1200
17 300
132 700
500 2300
5 9 400
输出:
9200

思路:

  • BFS 遍历图,使用邻接矩阵表示图的关联(距离);

  • 客户的id不一定是从1->n的连续整数,所以需要映射到1->n;

  • 一个客户有两种状态(已访问、未访问),n个客户有 2 n 2^n 2n种状态,n最大为10,所以最多 2 10 = 1024 2^{10}=1024 210=1024中状态;以客户id为列(从0开始,0为投递站),以每种状态为行,得到状态矩阵,广度优先遍历状态矩阵;
    在这里插入图片描述

  • 最后一种状态(2^n -1 行,0列)即为最短距离;



# 输入n m   n表示客户数   m 表示查询的路线
n, m = [int(x) for x in input().split()]

# (n + 1) * (n + 1) 邻接矩阵   顶点的关联(通过输入的距离 确定连通性)
matrix = [[float('inf') for i in range(n + 1)] for j in range(n + 1)]

# 客户 id 映射
# 防止客户id 不是1 - n的连续值
cid_map = [0 for _ in range(2000)]

# ****************更新matrix邻接矩阵*********************
#  输入 n 行数据
for i in range(n):
    cid, distance = [int(x) for x in input().split()]
    # 真实的客户id作为索引,映射的客户id作为值
    cid_map[cid] = i + 1  # 映射到1-n的连续值
    # 0 表示投递站,投递站与当前客户(映射后的id)的距离
    matrix[0][i + 1] = distance
    matrix[i + 1][0] = distance # 邻接矩阵是对称阵

# 输入m行 子查询的 距离
for i in range(m):
    cid1, cid2, distance = [int(x) for x in input().split()]
    # matrix 对称阵
    matrix[cid_map[cid1]][cid_map[cid2]] = distance
    matrix[cid_map[cid2]][cid_map[cid1]] = distance

# ****************更新matrix邻接矩阵*********************



# ****************状态矩阵的广度优先遍历*********************
# 保存客户访问状态 0表示投递站
# 因为有n个客户,所以最多有2的n次方个状态
# n最大为10, 所以最多1024个状态
cache = [[float('inf') for i in range(n + 1)] for j in range(1024)]

# 当前访问的客户状态以及距离
queue = []
queue.append([0, 0]) # [初始状态,客户映射id]  0表示投递站   1 2 3 .. 表示客户有映射id

# 投递站的初始状态  距离为0
cache[0][0] = 0

while True:
    if len(queue) <= 0:
        break
    else :
        pre_state, pre_cid = queue.pop(0)

        # 从当前position出发,到所有的客户
        i = 0 # 客户id  0 表示为投递站
        while True:
            if i > n: # 大于最大客户id
                break
            else:
                # 出发点->i 客户, 但i不能是出发点
                # 若i是出发点 或者  两者之间没有路线  则跳过
                if i == pre_cid or matrix[pre_cid][i] == float('inf'):
                    i += 1 # 走向下一个客户
                    continue

                # 新状态
                new_state = pre_state
                if i > 0: # 到达真实客户时,才更新状态
                    new_state = pre_state | pow(2, i-1) #

                if cache[new_state][i] > cache[pre_state][pre_cid] + matrix[pre_cid][i]:
                    # 当前状态下 对应客户i的距离
                    cache[new_state][i] = cache[pre_state][pre_cid] + matrix[pre_cid][i]
                    # 追加当前 [状态,客户]
                    queue.append([new_state, i])

            i += 1
# ****************状态矩阵的广度优先遍历*********************


# 打印状态 矩阵
for i in range(2**n):
    print("cache[%d]:" % i, cache[i])

# 输出最短距离
final_distance = cache[pow(2, n) - 1][0]
if final_distance == float('inf'):
    print(-1)
else :
    print(final_distance)


 

标签:distance,matrix,cid,OD,烦恼,投递,快递,客户,id
From: https://blog.csdn.net/weixin_45228198/article/details/136937671

相关文章

  • 【LeetCode 1220】统计元音字母序列的数目
    题目描述原题链接:LeetCode.1220统计元音字母序列的数目解题思路定义DP数组dp[i][j]含义为长度为i+1且以j字符结尾的字符串有多少个,j从0到4依次代表('a','e','i','o','u')这5个元音字符,dp[0][0~4]长度为1时的初始个数都为1;dp[i][j]对应字符串末尾字符已经由j确定,对应......
  • 【Godot4自学手册】第二十七节自定义状态机完成看守地宫怪物
    本节,我将使用自定义状态机实现看守地宫怪物,完成了基础类State,状态机类StateMachine的编码,实现了怪物的闲置巡逻类、追踪类和攻击类,以及对应动画等。这节代码有点多,不过还好,代码比较简单。最终效果如下:一、基本概念状态机(StateMachine)是有限状态自动机的简称,是指一个数学......
  • Kubernetes之Pod工作负载
    Pod工作负载,亦称Pod控制器。在Kubernetes平台上,我们很少会直接创建一个Pod,因为直接管理单个Pod的工作量将会非常繁琐。我们可以使用KubernetesAPI创建工作负载对象,这些对象所表达的是比Pod更高级别的抽象概念,Kubernetes 控制平面根据我们定义的工作负载对象规......
  • Spring Security 中的 BCryptPasswordEncoder
    一、使用BCryptPasswordEncoder加密的值可以解出来吗SpringSecurity中的BCryptPasswordEncoder是一种单向加密算法,它是为了安全性考虑而设计的,因此无法从加密后的密码值"解密"出原始密码。这是出于安全目的的设计。BCryptPasswordEncoder加密过程是不可逆的,即使......
  • Codeforces Round 936 (Div. 2) D
    AB没什么好说的C二分答案,写的还是不够快,但是也很好了。D的问题有点大。我好像一直有一个不对的贪心再用,对于二进制的。就是我会觉得一堆树或起来小于一个数字,这种限制是每个数字都小于那个数字就可以了。但是实际上这就是一个很明显错误的贪心。然后另一个反映就是,对于二进......
  • My understanding of pedagogic metalanguage in "The Three-Body Problem "
    ......
  • 代码随想录算法训练营day31 | leetcode 455. 分发饼干、376. 摆动序列、53. 最大子数
    目录贪心理论基础核心:题目链接:455.分发饼干-简单题目链接:376.摆动序列-中等题目链接:53.最大子数组和-中等贪心理论基础核心:由局部推全局最优题目链接:455.分发饼干-简单题目描述:假设你是一位很棒的家长,想要给你的孩子们一些小饼干。但是,每个孩子最多只能给一块饼干。对每......
  • mongoDB使用记录:副本集选举淘汰策略失效
    一个问题场景:业务请求查询数据库,当请求没有成功返回时(这里是数据库机器异常,表现是不返回请求结果,处于假死状态),业务挂起进入等待(WAIT),逻辑中断,表现为卡顿、持续加载中;高并发场景下,短时间内堆积的请求会大量占用发起数据库请求的机器的内存(风险一),大量业务卡顿异常;当数据库异常解决成......
  • c++解耦:Factory Method
    讨论C++语言中如何将通用逻辑与使用到的频繁变化的具体类型解耦。假设存在以下设计:/*==================================================================*/#include<iostream>classCore{public:~Core(){}public:voidsolve(){std::cout<<"Cor......
  • mongoDB使用记录:误用数组索引
    版本:mongoDB4.2集群方案:副本+分片一个问题场景:集合内对多个字段建立索引,其中包含数组索引;当执行查询时,业务查询期望命中数组索引,mongodb筛选策略首次给出的执行方案命中了另外的索引key,导致当次慢查询,扫描超过1000w数量的文档,业务出现卡顿;处理&优化方案:mongodb筛选策略命中......