解决leetcode第3977题有限电量到达目标节点的最少时间

3977.有限电量到达目标节点的最少时间

难度:困难

问题描述:

给你一个有n个节点的有向加权图,节点编号从0到n-1。

该图由一个二维整数数组edges表示,其中edgesi=ui,vi,ti表示一条从节点ui到节点vi的有向边,通过该边需要花费ti秒。

同时给你一个整数power表示初始可用电量,以及一个长度为n的整数数组cost,其中costu表示从节点u通过任意一条出边转发信号所需的电量。

给你两个整数source和target。

信号在时间0从source出发,拥有power单位的电量,并遵循以下规则:

只有当剩余电量至少为costu时,信号才能遍历从节点u出发的有向边。

信号到达一个节点时不消耗任何电量,除非它稍后通过另一条边离开该节点。

当信号从节点u转发时,剩余电量将减少costu个单位。

遍历一条边edgesi=ui,vi,ti会使总时间增加ti秒。

返回一个大小为2的整数数组answer,其中:

answer0是信号到达节点target所需的最小时间。

answer1是所有实现answer0的路径中最大的剩余电量。

如果信号无法到达target,则返回-1,-1

示例1:

输入:n=5,edges=\[0,1,1,1,4,1,0,2,1,2,3,1,3,4,1],power=4,cost=2,3,1,1,1,source=0,target=4

输出:3,0

解释:

信号从节点0出发,拥有4个单位的电量。

路径0->1->4无效,因为离开节点0后,信号剩余2个单位的电量,这小于cost1=3。

有效路径0->2->3->4总共花费时间为3。

沿着这条路径消耗的总电量为cost0+cost2+cost3=4,剩余电量为0。

因此,答案为3,0

示例2:

输入:n=3,edges=\[0,1,2,1,2,2,2,0,2],power=3,cost=1,1,1,source=1,target=1

输出:0,3

解释:

由于source和target是同一个节点,不需要通过任何节点。

因此,花费的最小总时间为0,并且不消耗电量。

因此,答案为0,3

示例3:

输入:n=4,edges=\[0,1,3,2,3,4],power=3,cost=1,1,1,1,source=0,target=3

输出:-1,-1

解释:

没有从source到target的有效路径,因此返回-1,-1

提示:

1<=n<=1000

0<=edges.length<=1000

edgesi=ui,vi,ti

0<=ui,vi<=n-1

1<=ti<=10**9

1<=power<=1000

cost.length==n

1<=costi<=2000

0<=source,target<=n-1​

问题分析:

本题在输入原始数据时,节点数n可以不输入,因为cost的数据长度决定了节点的个数,同时edges中也可以看出最大节点,这些都可以确定节点个数n的值,所以在本题中没有输入n的环节。

要从source节点通过有向边到达target节点,首先是在edges中找到所有起始节点为source的有向边,然后从这些有向边开始遍历其它有向边,如果最终能够到达target节点,将这些从source到target的有向边存储起来,最后在主程序中根据这些有向边的数据信息和cost中消耗的电量信息将各条路径到达target节点消耗电量之后剩余的电量以及所需要的时间以列表的方式给出,再找出其中时间最短但剩余的电量最大输出即可,如果surce和target相同,则直接给出结果0,power

程序如下:

python 复制代码
#根据给定的source_edge,如果能够在edges中能够形成一条完整的路径,返回路径,否则返回空路径
def get_one_paths(edges,source_edge,target):
    paths = []
    s=source_edge[0]
    t=source_edge[1]
    paths.append(source_edge)
    if t==target:
        return paths
    n=len(edges)
    for i in range(1,n):
        s=t
        for j in edges:
            if j[0]==s:
                t=j[1]
                if t==target:
                    paths.append(j)
                    return paths
                else:
                    paths.append(j)
    else:
        return []

#根据有向节点,找出所有从source到target的所有路径并返回
def get_all_paths(edges,source,target):
    paths = []
    sources=list(x for x in edges if x[0]==source )
    for i in sources:
        path=get_one_paths(edges,i,target)
        if path!=[]:
            paths.append(path)
    return paths

#主程序
edges=eval(input("enter the edges= "))
power=int(input("enter the power= "))
cost=eval(input("enter the cost= "))
source=eval(input("enter the source= "))
target=eval(input("enter the target= "))
if source==target:
    result=[0,power]
else:
    paths = get_all_paths(edges, source, target)
    t = []
    for i in paths:
        e = list(x[0] for x in i)
        p = power - sum(list(cost[x] for x in e))
        s = sum(list(x[2] for x in i))
        if p >= 0:
            t.append([s, p])
    if t == []:
        result=[-1,-1]
    else:
        a = min(list(x[0] for x in t))
        b = max(list(x[1] for x in t if x[0] == a))
        result=[a,b]
print(result)

运行实例一

​​enter the edges= \[0,1,1,1,5,1,0,2,1,2,5,1,2,3,2,3,4,1,4,5,1]

enter the power= 4

enter the cost= 1,2,1,1,1

enter the source= 0

enter the target= 5

2, 2​​

运行实例二

enter the edges= \[0,1,2,1,2,2,2,0,2]

enter the power= 3

enter the cost= 2,2,2

enter the source= 1

enter the target= 1

0, 3

运行实例三

enter the edges= \[0,1,2,3,4,2]

enter the power= 3

enter the cost= 2,2,2,2

enter the source= 0

enter the target= 3

-1, -1​​