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:
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 1≤i≤Q, 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
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 1≤i≤Q) 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 3→4→1, and cities 3 → 5 → 1 3→5→1 3→5→1. 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 4→1→3→5, 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 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;
}
今天就到这里了!
大家有什么问题尽管提,我都会尽力回答的!最后,除夕夜祝大家新年快乐!
吾欲您伸手,点的小赞赞。吾欲您喜欢,点得小关注!