[Python/C++](PAT)1003 Emergency (25)

43 篇文章 0 订阅

As an emergency rescue team leader of a city, you are given a special map of your country. The map shows several scattered cities connected by some roads. Amount of rescue teams in each city and the length of each road between any pair of cities are marked on the map. When there is an emergency call to you from some other city, your job is to lead your men to the place as quickly as possible, and at the mean time, call up as many hands on the way as possible.

Input

Each input file contains one test case. For each test case, the first line contains 4 positive integers: N (<= 500) – the number of cities (and the cities are numbered from 0 to N-1), M – the number of roads, C1 and C2 – the cities that you are currently in and that you must save, respectively. The next line contains N integers, where the i-th integer is the number of rescue teams in the i-th city. Then M lines follow, each describes a road with three integers c1, c2 and L, which are the pair of cities connected by a road and the length of that road, respectively. It is guaranteed that there exists at least one path from C1 to C2.

Output

For each test case, print in one line two numbers: the number of different shortest paths between C1 and C2, and the maximum amount of rescue teams you can possibly gather.\ All the numbers in a line must be separated by exactly one space, and there is no extra space allowed at the end of a line.

Sample Input

 

1

2

3

4

5

6

7

8

5 6 0 2

1 2 1 5 3

0 1 1

0 2 2

0 3 1

1 2 1

2 4 1

3 4 1

Sample Output

 

1

2 4

 

题目大意:
给定一张城市的地图,你需要从C1到C2去救灾。给定城市之间连通的道路以及各个城市救灾部队的数量。问从起点到终点的最短路径有几条,这些最短路径中,能最多带走多少救灾部队?

分析:
道路的长度相当于道路的边权,救灾部队的数量相当于点的点权。使用dijkstra算法求解最短路径的同时求最大的点权。

变量定义:
weight数组存储从起点到索引表示点的最短路径长度
power数组存储从起点到索引表示点的最大点权
num数组存储从起点到索引表示点有几条最短路径
point数组表示索引表示的点的点权

算法大致过程:
使用visted数组对点进行标号,每一次从没有标号的点中找到总边权最少的点,给予标号。下一次循环从这个最新给予标号的点开始,探索与它联通的非标号点:
如果weight[i] < weight[x] + route[x][i]的话,更新该点的总边权和点权,num[i] =    num[x];如果取等号,则视情况更新点权,num[i] = num[i] + num[x]

最后输出num[c2]和power[c2]

Python实现

Python

if __name__ == "__main__":
    line = input().split(" ")
    n = int(line[0])
    m = int(line[1])
    c1 = int(line[2])
    c2 = int(line[3])
    line = input().split(" ")
    point = [int(x) for x in line]
    route = [[0 for x in range(n)] for i in range(n)]
    for x in range(m):
        line = input().split(" ")
        a = int(line[0])
        b = int(line[1])
        c = int(line[2])
        route[a][b] = c
        route[b][a] = c
    visted = [0 for x in range(n)]
    weight = [float('inf') for x in range(n)]
    power = [0 for x in range(n)]
    weight[c1] = 0
    power[c1] = point[c1]
    visted[c1] = 1
    x = c1
    num = [0 for x in range(n)]
    num[c1] = 1
    while visted[c2] == 0:
        for i in range(n):
            if route[x][i] != 0 and visted[i] != 1:
                if weight[i] >= weight[x] + route[x][i]:

                    if weight[i] == weight[x] + route[x][i]:
                        num[i] = num[i] + num[x]
                        if power[i] < power[x] + point[i]:
                            power[i] = power[x] + point[i]
                    else:
                        if weight[i] > weight[x] + route[x][i]:
                            power[i] = power[x] + point[i]
                            num[i] = num[x]
                    weight[i] = weight[x] + route[x][i]
        small = sorted([weight[x] for x in range(n) if visted[x] != 1])[0]
        index = [x for x in range(n) if weight[x] == small and visted[x] != 1][0]
        visted[index] = 1
        x = index

    print(num[c2], power[c2])

C++实现 https://www.liuchuo.net/archives/2359

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值