洛谷题解-[ABC286E] Souvenir (Floyd)

https://www.luogu.com.cn/problem/AT_abc286_e

题目描述

N N N 個の都市があり、いくつかの相異なる都市の間は一方通行の直行便によって移動することができます。
どの直行便が存在するかは N N N 個の長さ N N N の文字列 S1,S2,…,SN S_1,S_2,\ldots,S_N S1,S2,,SN によって表され、 Si S_i Sij j j 文字目が Y のとき都市 i i i から都市 j j j へ向かう直行便が存在することを、 N のとき存在しないことを示します。
また、各都市ではお土産が 1 1 1 つずつ売られており、都市 i i i では価値 Ai A_i Ai のお土産が売られています。

次のような問題を考えます。

高橋君は今都市 S S S におり、いくつかの直行便を乗り継いで(S S S とは異なる)都市 T T T に向かおうとしています。
さらに、高橋君は移動する途中で訪れた都市(S,T S,T S,T を含む)において 1 1 1 つずつお土産を購入します。
都市 S S S から都市 T T T へ向かう経路が複数存在する時、高橋君は次のような経路で移動することを考えています。

  • 都市 S S S から 都市 T T T に向かう経路のうち、使う直行便の数が最小である。
  • さらにそのような経路のうち、購入するお土産の価値の総和が最大である。

高橋君が都市 S S S から T T T に直行便を乗り継いで移動することが可能か判定し、 可能な時は高橋君が上の条件をみたすように経路を選んだ時の「使用する直行便の本数」と「お土産の価値の総和」を求めよ。

相異なる都市の組 (Ui,Vi) (U_i,V_i) (Ui,Vi) が Q Q Q 個与えられます。
1≤ i≤ Q 1\leq\ i\leq\ Q 1 i Q について、S=Ui, T=Vi S=U_i,\ T=V_i S=Ui, T=Vi とした時の上記の問題の答えを出力してください。

输入格式

入力は以下の形式で標準入力から与えられる。

N N N A1 A_1 A1 A2 A_2 A2 … \ldots AN A_N AN S1 S_1 S1 S2 S_2 S2 ⋮ \vdots SN S_N SN Q Q Q U1 U_1 U1 V1 V_1 V1 U2 U_2 U2 V2 V_2 V2 ⋮ \vdots UQ U_Q UQ VQ V_Q VQ

输出格式

Q Q Q 行出力せよ。
i i i (1≤ i≤ Q) (1\leq\ i\leq\ Q) (1 i Q) 行目には、 都市 Ui U_i Ui から都市 Vi V_i Vi に移動することが不可能な時は Impossible を、 可能な時は上記のように経路を選んだ時の「使用する直行便の本数」と「お土産の価値の総和」をこの順に空白区切りで出力せよ。

题意翻译

题目描述

从前有 nnn 座岛,每个岛上有 aia_iai 个金币,各个岛间有若干条单向航线相连。

你从某个岛开始旅行,经过一个岛(包括最开始所在的岛)就会拿走上面的金币。

现在问你 qqq 个问题:从岛 uiu_iui 旅行到岛 viv_ivi,最少要走几条航线,以及恰好走这么多条航线最多能获得多少金币。如果根本无法到达 viv_ivi,输出 Impossible

询问之间相互独立。

输入格式

输入第一行一个整数 nnn 表示岛的数量。

接下来一行 nnn 个整数表示每个岛上的金币数。

接下来 nnn 行每行一个长为 nnn 的字符串,第 iii 行字符串的第 jjj 个字符若为 Y 则表示岛 iii 和 jjj 间有单向航线,否则表示没有。

接下来一行一个整数 qqq 表示询问次数。

最后 qqq 行每行两个整数 ui,viu_i,v_iui,vi,询问你从岛 uiu_iui 旅行到岛 viv_ivi 最少要走几条航线,以及恰好走这么多条航线最多能获得多少金币。

输出格式

对于每个询问输出一行:

  • uiu_iui 不能到达 viv_ivi,输出 Impossible
  • 否则,输出从岛 uiu_iui 旅行到岛 viv_ivi 最少要走几条航线,以及恰好走这么多条航线最多能获得多少金币。

样例解释 1

这些岛的结构如下:

  • 对于第 111 个询问,因为岛 111 有一条航线通往岛 333,显然最少航线为 111 条,此时能拿到岛 111 和岛 333 上的金币共 30+70=10030+70=10030+70=100 个。
  • 对于第 222 个询问,可以证明最少航线为 222 条,有两种方案 3→4→13 \rarr 4 \rarr 1341 和 3→5→13 \rarr 5 \rarr 1351,总金币分别为 70+20+30=12070+20+30=12070+20+30=120 和 70+60+30=16070+60+30=16070+60+30=160,故最多金币为 160160160。
  • 对于第 333 个询问,只有一种方案 4→1→3→54 \rarr 1 \rarr 3 \rarr 54135 可以使航线数最少为 333,所得金币为 20+30+70+60=18020+30+70+60=18020+30+70+60=180。

样例解释 2

笑死,连航线都没有。

数据范围与约定

对于 100%100\%100% 的数据,2≤n≤300,1≤ai≤109,1≤q≤n(n−1),1≤ui,vi≤n2\le n\le 300,1\le a_i\le 10^9,1\le q\le n(n-1),1\le u_i,v_i\le n2n300,1ai109,1qn(n1),1ui,vin,且询问中的 ui,viu_i,v_iui,vi 各不相同。

翻译者:not_Rick_Astley

输入输出样例

输入 #1
5

30 50 70 20 60

NYYNN

NNYNN

NNNYY

YNNNN

YNNNN

3

1 3

3 1

4 5
输出 #1
1 100

2 160

3 180
输入 #2
2

100 100

NN

NN

1

1 2
输出 #2
Impossible

说明/提示

制約

  • 2 ≤ N ≤ 300 2\ \leq\ N\ \leq\ 300 2  N  300
  • 1≤ Ai≤ 109 1\leq\ A_i\leq\ 10^9 1 Ai 109
  • Si S_i SiYN のみからなる長さ N N N の文字列
  • Si S_i Sii i i 文字目は N
  • 1≤ Q≤ N(N−1) 1\leq\ Q\leq\ N(N-1) 1 Q N(N1)
  • 1≤ Ui,Vi≤ N 1\leq\ U_i,V_i\leq\ N 1 Ui,Vi N
  • Ui≠ Vi U_i\neq\ V_i Ui= Vi
  • i≠ j i\neq\ j i= j ならば (Ui,Vi)≠ (Uj,VJ) (U_i,V_i)\neq\ (U_j,V_J) (Ui,Vi)= (Uj,VJ)
  • N,Ai,Q,Ui,Vi N,A_i,Q,U_i,V_i N,Ai,Q,Ui,Vi は全て整数

Sample Explanation 1

(S,T)=(U1,V1)=(1,3) (S,T)=(U_1,V_1)=(1,3) (S,T)=(U1,V1)=(1,3) の時について、都市 1 1 1 から都市 3 3 3 への直行便が存在するため、 使用する直行便としてあり得る最小の値はその直行便を使用した時の 1 1 1 本となります。 この時、お土産の価値の総和は A1+A3=30+70=100 A_1+A_3=30+70=100 A1+A3=30+70=100 となります。 (S,T)=(U2,V2)=(3,1) (S,T)=(U_2,V_2)=(3,1) (S,T)=(U2,V2)=(3,1) の時について、使用する直行便としてあり得る最小の値は 2 2 2 本で、 最小値を達成する経路としては都市 3→ 4→ 1 3\to\ 4\to\ 1 3 4 1 と都市 3→ 5→ 1 3\to\ 5\to\ 1 3 5 1 の 2 2 2 通りが考えられます。 それぞれの経路の時のお土産の価値の総和は 70+20+30=120 70+20+30=120 70+20+30=120, 70+60+30=160 70+60+30=160 70+60+30=160 なので、 高橋君は後者の経路を選び、この時お土産の価値の総和は 160 160 160 となります。 (S,T)=(U3,V3)=(4,5) (S,T)=(U_3,V_3)=(4,5) (S,T)=(U3,V3)=(4,5) の時について、都市 4→ 1→ 3→ 5 4\to\ 1\to\ 3\to\ 5 4 1 3 5 と進んだ時に使用する直行便の本数は最小となり、 この時お土産の価値の総和は 20+30+70+60=180 20+30+70+60=180 20+30+70+60=180 となります。

Sample Explanation 2

直行便が全く存在しないこともあります。

 

 

1.数据较大开longlong

2.Floyd转移方程不一定用取min函数,还可以判断并加上别的条件

3.可以分类,为确定了最短路前,和确定了最短路后分开写一些条件

#include <bits/stdc++.h>
#define int long long //注意
using namespace std;

const int N=305;
int n, my[N], q, u1, v1, dis[N][N], dis2[N][N];
char s;
void floyd()
{
	for (int k=1; k<=n; k++)
		for (int i=1; i<=n; i++)
			for (int j=1; j<=n; j++)
			{
				if (dis2[i][j]>dis2[i][k]+dis2[k][j]) //用if判断也可以,为了是
				{
					dis[i][j]=dis[i][k]+dis[k][j]; //为了这条,在最短路没确定之前,最大价值先是这条路上的值
					dis2[i][j]=dis2[i][k]+dis2[k][j];
				} 
				else if (dis2[i][j]==dis2[i][k]+dis2[k][j]) //确定好了最短路
					dis[i][j]=max(dis[i][j], dis[i][k]+dis[k][j]); //取个最大值,新路和原来的路的值
			}
				
} 
signed main()
{
	scanf("%lld", &n);
	for (int i=1; i<=n; i++) 
		scanf("%lld", &my[i]);
	
	memset(dis2, 63, sizeof dis2);
	for (int i=1; i<=n; i++)
	{
		for (int j=1; j<=n; j++)
		{
			cin>>s;
			if (s=='Y')
				dis[i][j]=my[j], dis2[i][j]=1;
		}
	}
	floyd();
	
	scanf("%lld", &q);
	while (q--)
	{
		scanf("%lld%lld", &u1, &v1);
		if (dis2[u1][v1]==dis2[0][0]) printf("Impossible\n");
		else printf("%lld %lld\n", dis2[u1][v1], dis[u1][v1]+my[u1]);
	}
	return 0;
}

 

 

posted @ 2024-01-29 19:24  cn是大帅哥886  阅读(90)  评论(0)    收藏  举报