题目:宝石合成 python题解

题目描述

J想要创造n种魔法宝石。J可以用ai的魔力值创造一出第 i  种魔法宝石,或是使用两个宝石合成另一种宝石(不消耗魔力值)。请你帮J算出合成某种宝石的所需的最小花费。

输入
首先一行为n,m(1≤n,m≤10^5)。分别表示魔法宝石种类数和合成魔法的数量。
之后一行n个数表示a1到an。(1≤ai≤10^9)。a_i表示合成第i种宝石所需的魔力值。
之后n行,每行三个数a,b,c(1≤a,b,c≤n),表示一个第a种宝石和第b种宝石,可以合成一个第c种宝石。

输出
每组数据输出一行n个数,其中第i个数表示合成第i种宝石的魔力值最小花费。

数据范围
1 <= n <= 100000,1 <= m<= 100000,1≤a,b,c≤n

输入样例
3 1
1 1 10
1 2 3

输出样例
1 1 2

样例解释
第一个宝石花费1,第二个宝石花费1,第三个宝石可以由第一个第二个宝石合成花费2。

题目分析

注意题目中并没有提出n 和 m 的值的大小。即可能出现一种宝石不止一种合成方法。

一开始我联想到的是动态规划,感觉有那么一些的关系。但是写到一半发先状态转移方程我找不到,各阶段也不是固定的,才发现好像写不了(我动态规划确实没好好学哈哈哈哈,之后再写)

代码

 这个是我写的代码 应该是能通过的。嘿嘿嘿我也没试过

n, m = map(int, input().split(' '))
a = list(map(int, input().split(' ')))
a.insert(0, 0)   # 在开头添加一个数 方便调用
a = [(i, j) for i, j in enumerate(a)]  # ai = (序号,花费的法力)

comb = dict()   # 用字典存放合成表
for i in range(n):
    comb[a[i + 1][0]] = []
for i in range(m):
    temp = list(map(int, input().split(' ')))
    comb[temp[2]].append(temp[:2])


min_a = [-1 for i in range(n + 1)]  # 表示第i个i的最小花费 -1 表示没找到最小值 一开始都没有最小值
# 无合成表 最小花费为本身 有合成表 看合成表中的最小值是否已知,已知则可计算。 min_i= min(ai, min_j +min_K)

p = [i for i in range(1, n + 1)]  # 调查队列

while p:
    x = p.pop(0)
    if not comb[x]:  # 没有合成表 最小值则为直接合成的法力值
        min_a[x] = a[x][1]
    else:  # 有合成表 找最小的
        flag = 0  # 0 表示合成表中的最小值都已知
        for i in range(len(comb[x])):  # x 有几种合成方式
            for j in range(2):
                if min_a[comb[x][i][j]] == -1:  # 有一个值没找到最值
                    flag = 1
        if flag == 1:
            p.append(x)
        else:  # 都有最值
            ans = [a[x][1]]
            for i in range(len(comb[x])):
                ans.append(min_a[comb[x][i][0]] + min_a[comb[x][i][1]])
            min_a[x] = min(ans)

ans = [f'{i}' for i in min_a[1:]]
print(" ".join(ans))

ac代码

n, m = map(int, input().split(' '))
magic = list(map(int, input().split(' ')))
magic.insert(0, -1)

path = []
for _ in range(0, m):
    path.append(list(map(int, input().split(' '))))

flag = True
while flag:
    flag = False
    for i in range(m):
        a, b, c = path[i]
        if magic[a] + magic[b] < magic[c]:  # 如果有一个的值能变的更小则继续遍历 当所有的值都不能压缩时则全都到了最小值还是比较好想的
            magic[c] = magic[a] + magic[b]
            flag = True

print(str(magic[1:]).replace(',', '')[1:-1])  # 最后的[1:-1]是为了去掉 “中括号‘

备注

若有错误,欢迎各位一起探讨。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值