AtCoder Beginner Contest 286——E - Souvenir

AtCoder Beginner Contest 286 题目讲解

A题 B题 C题 D题 E题


蒟蒻来讲题,还望大家喜。若哪有问题,大家尽可提!

Hello, 大家好哇!本初中生蒟蒻今天讲解一下AtCoder Beginner Contest 286的E题——Souvenir

===========================================================================================

原题

Problem Statement

There are N N N cities. There are also one-way direct flights that connect different cities.
The availability of direct flights is represented by N N N strings S 1 ​ , S 2 ​ , … , S N S_{1}​,S_{2}​,…,S_{N} S1,S2,,SN​ of length N N N each. If the j j j-th character of S i S_{i} Si​ is Y Y Y, there is a direct flight from city i i i to city j j j; if it is N N N, there is not.
Each city sells a souvenir; city i sells a souvenir of value A i A_{i} Ai​.

Consider the following problem:

Takahashi is currently at city S S S and wants to get to city T T T (that is different from city S S S) using some direct flights.
Every time he visits a city (including S S S and T T T), he buys a souvenir there.
If there are multiple routes from city S S S to city T T T, Takahashi decides the route as follows:

  • He tries to minimize the number of direct flights in the route from city S to city T T T.
  • Then he tries to maximize the total value of the souvenirs he buys.

Determine if he can travel from city S S S to city T T T using the direct flights. If he can, find the “number of direct flights” and “total value of souvenirs” in the route that satisfies the conditions above.

You are given Q Q Q pairs ( U i ​ , V i ​ ) (U_{i}​,V_{i}​) (Ui,Vi) of distinct cities.
For each 1 ≤ i ≤ Q 1\leq i\leq Q 1iQ, print the answer to the problem above when S = U i S=U_{i} S=Ui​ and T = V i T=V_{i} T=Vi​.

Constraints

  • 2 ≤ N ≤ 300 2\leq N\leq 300 2N300
  • 1 ≤ A i ​ ≤ 1 0 9 1\leq A_{i}​\leq10^9 1Ai109
  • S i S_{i} Si​ is a string of length
  • N N N consisting of Y Y Y and N N N.
  • The i i i-th character of S i S_{i} Si​ is N N N.
  • 1 ≤ Q ≤ N ( N − 1 ) 1\leq Q\leq N(N−1) 1QN(N1)
  • 1 ≤ U i ​ , V i ​ ≤ N 1\leq U_{i​},V_{i}​\leq N 1Ui,ViN
  • U i ​ ≠ V i Ui​\neq Vi Ui=Vi
  • If i ≠ j i\neq j i=j, then ( U i ​ , V i ​ ) ≠ ( U j ​ , V J ​ ) (U_{i}​,V_{i}​)\neq (U_{j}​,V_{J}​) (Ui,Vi)=(Uj,VJ).
  • N , A i ​ , Q , U i ​ , N,A_{i}​,Q,U_{i}​, N,Ai,Q,Ui, and V i V_{i} Vi​ are all integers.

Input

The input is given from Standard Input in the following format:

N
A1​  A2​  …  AN​
S1​
S2​
⋮
SN​
Q
U1​  V1​
U2​  V2​
⋮
UQ​  VQ​

Output

Print Q Q Q lines.
The i i i-th ( 1 ≤ i ≤ Q 1\leq i\leq Q 1iQ) line should contain Impossible if he cannot travel from city U i U_{i} Ui​ to city V i V_{i} Vi​; if he can, the line should contain “the number of direct flights” and “the total value of souvenirs” in the route chosen as described above, in this order, separated by a space.

Sample Input 1

5
30 50 70 20 60
NYYNN
NNYNN
NNNYY
YNNNN
YNNNN
3
1 3
3 1
4 5

Sample Output 1

1 100
2 160
3 180

For ( S , T ) = ( U 1 ​ , V 1 ​ ) = ( 1 , 3 ) (S,T)=(U_{1}​,V_{1}​)=(1,3) (S,T)=(U1,V1)=(1,3), there is a direct flight from city 1 1 1 to city 3 3 3, so the minimum possible number of direct flights is 1 1 1, which is achieved when he uses that direct flight. In this case, the total value of the souvenirs is A 1 ​ + A 3 ​ = 30 + 70 = 100 A_{1}​+A_{3}​=30+70=100 A1+A3=30+70=100.
For ( S , T ) = ( U 2 ​ , V 2 ​ ) = ( 3 , 1 ) (S,T)=(U2​,V2​)=(3,1) (S,T)=(U2​,V2​)=(3,1), the minimum possible number of direct flights is 2 2 2. The following two routes achieve the minimum: cities 3 → 4 → 1 3→4→1 341, and cities 3 → 5 → 1 3→5→1 351. Since the total value of souvenirs in the two routes are 70 + 20 + 30 = 120 70+20+30=120 70+20+30=120 and 70 + 60 + 30 = 160 70+60+30=160 70+60+30=160, respectively, so he chooses the latter route, and the total value of the souvenirs is 160 160 160.
For ( S , T ) = ( U 3 ​ , V 3 ​ ) = ( 4 , 5 ) (S,T)=(U_{3}​,V_{3}​)=(4,5) (S,T)=(U3,V3)=(4,5), the number of direct flights is minimum when he travels cities 4 → 1 → 3 → 5 4→1→3→5 4135, where the total value of the souvenirs is 20 + 30 + 70 + 60 = 180 20+30+70+60=180 20+30+70+60=180.

Sample Input 2

2
100 100
NN
NN
1
1 2

Sample Output 2

Impossible

There may be no direct flight at all.


思路

这道题一看就可以用我们的 D i j k s t r a Dijkstra Dijkstra了,但是, D i j k s t r a Dijkstra Dijkstra只能求出最短路径,不能求出最短路径的最大价值。不过,我们可以再开一个数组 r e s res res,记录价值。

  • 如果 d i s t [ i ] [ j ] > d i s t [ i ] [ t ] + g [ t ] [ j ] dist[i][j] > dist[i][t]+g[t][j] dist[i][j]>dist[i][t]+g[t][j]就说明有一条最短路径,因为短优先,所以直接让 r e s [ i ] [ j ] = r e s [ i ] [ t ] + a [ j ] res[i][j] = res[i][t] + a[j] res[i][j]=res[i][t]+a[j]
  • 如果 d i s t [ i ] [ j ] = d i s t [ i ] [ t ] + g [ t ] [ j ] dist[i][j] = dist[i][t]+g[t][j] dist[i][j]=dist[i][t]+g[t][j]就说明最短路径相等,那我们就要求最大值,即为 r e s [ i ] [ j ] = m a x ( r e s [ i ] [ j ] , r e s [ i ] [ t ] + a [ j ] ) res[i][j] = max(res[i][j], res[i][t]+a[j]) res[i][j]=max(res[i][j],res[i][t]+a[j])

不过每次调用 D i j k s t r a Dijkstra Dijkstra会超时,所以我们要先预处理一下,把任一点到任一点枚举一遍因为点的数量很少,这样就是 O ( N 3 ) O(N^3) O(N3)的时间复杂度,就可以过了!


代码

#include 
#include 
#define int long long //本题要开long long!

using namespace std;

const int N = 5e2 + 10;

int n, m;
int g[N][N], dist[N][N]; //定义邻接矩阵和最短距离数组
int cost[N];
int res[N][N];//最短距离下的最大价值
bool st[N];

void dijkstra()
{
	for (int i = 0; i <= n; i ++)
		for (int j = 0; j <= n; j ++)
			dist[i][j] = 1e18;

    for (int i = 1; i <= n; i ++)
    {
    	dist[i][i] = 0;
    	memset(st, 0, sizeof st);
    	for (int k = 0; k < n - 1; k ++)
    	{
	        int t = -1;
	        for (int j = 1; j <= n; j ++)
	            if (!st[j] && (t == -1 || dist[i][t] > dist[i][j]))
	                t = j;
	
	        st[t] = 1;
	
	        for (int j = 1; j <= n; j ++)
	        {
	        	if (dist[i][j] > dist[i][t] + g[t][j]) //说明有最短路径
	        	{
	            	dist[i][j] = dist[i][t] + g[t][j];
	            	res[i][j] = res[i][t] + cost[j]; //必须选
	            }
	            else if (dist[i][j] == dist[i][t] + g[t][j]) //长度相等
	            	res[i][j] = max(res[i][j], res[i][t] + cost[j]); //选择价值大的
	        }
	    }
    }
}

signed main()
{
    cin >> n;

    for (int i = 1; i <= n; i ++)
    	for (int j = 1; j <= n; j ++)
    		g[i][j] = 1e18;
    
    for (int i = 1; i <= n; i ++)
    	cin >> cost[i];

	for (int i = 1; i <= n; i ++)
	{
		string s;
		cin >> s;
		for (int j = 0; j < n; j ++)
			if (s[j] == 'Y')
				g[i][j + 1] = 1; //边权赋值为1
	}
	
	dijkstra();
	
	cin >> m;
	
    int a, b;
    while (m --)
    {
        cin >> a >> b;
		
		if (dist[a][b] >= 1e18) cout << "Impossible" << endl;
        else cout << dist[a][b] << " " << res[a][b] + cost[a] << endl; //要加起点!
    }
    
    return 0;
}

今天就到这里了!

大家有什么问题尽管提,我都会尽力回答的!最后,除夕夜祝大家新年快乐!
在这里插入图片描述

吾欲您伸手,点的小赞赞。吾欲您喜欢,点得小关注!

你可能感兴趣的:(算法-Dijkstra,c++)