A. Odd One Out
题面翻译
t t t 组数据。每次给出三个数字 a , b , c a,b,c a,b,c,其中有两个数字是相等的,输出那个不相等的数字。
translated by @coderJerry
题目描述
You are given three digits $ a $ , $ b $ , $ c $ . Two of them are equal, but the third one is different from the other two.
Find the value that occurs exactly once.
输入格式
The first line contains a single integer $ t $ ( $ 1 \leq t \leq 270 $ ) — the number of test cases.
The only line of each test case contains three digits $ a $ , $ b $ , $ c $ ( $ 0 \leq a $ , $ b $ , $ c \leq 9 $ ). Two of the digits are equal, but the third one is different from the other two.
输出格式
For each test case, output the value that occurs exactly once.
样例 #1
样例输入 #1
10
1 2 2
4 3 4
5 5 6
7 8 8
9 0 9
3 6 3
2 8 2
5 7 7
7 7 5
5 7 5
样例输出 #1
1
3
6
7
0
6
8
5
5
7
代码
#include<iostream>
#include<map>
using namespace std;
int T;
int a,b,c;
int main(){
cin>>T;
while(T--){
cin>>a>>b>>c;
map<int,int>k;
k[a]++,k[b]++,k[c]++;
for(auto& [v,w]:k){
if(w==1){
cout<<v<<endl;
break;
}
}
}
return 0;
}
B. Not Quite Latin Square
题面翻译
t
t
t 组数据。每次给出一个由 A B C
组成的
3
×
3
3\times3
3×3 的矩阵,矩阵满足的条件为:每行每列有且仅有各
1
1
1 个 A B C
。现在有一个字符被替换成了 ?
,求出 ?
代表的字符。
translated by @coderJerry
题目描述
A Latin square is a $ 3 \times 3 $ grid made up of the letters $ \texttt{A} $ , $ \texttt{B} $ , and $ \texttt{C} $ such that:
- in each row, the letters $ \texttt{A} $ , $ \texttt{B} $ , and $ \texttt{C} $ each appear once, and
- in each column, the letters $ \texttt{A} $ , $ \texttt{B} $ , and $ \texttt{C} $ each appear once.
For example, one possible Latin square is shown below. $ $KaTeX parse error: Can't use function '$' in math mode at position 151: … \end{bmatrix} $̲ $ <p>You are g…$. Find the letter that was replaced.
输入格式
The first line of the input contains a single integer $ t $ ( $ 1 \leq t \leq 108 $ ) — the number of testcases.
Each test case contains three lines, each consisting of three characters, representing the Latin square. Each character is one of $ \texttt{A} $ , $ \texttt{B} $ , $ \texttt{C} $ , or $ \texttt{?} $ .
Each test case is a Latin square with exactly one of the letters replaced with a question mark $ \texttt{?} $ .
输出格式
For each test case, output the letter that was replaced.
样例 #1
样例输入 #1
3
ABC
C?B
BCA
BCA
CA?
ABC
?AB
BCA
ABC
样例输出 #1
A
B
C
提示
The correct Latin squares for the three test cases are shown below:
$ $KaTeX parse error: Can't use function '$' in math mode at position 502: … \end{bmatrix} $̲ $
代码(思路很简单)
#include<iostream>
#include<map>
using namespace std;
const int N = 5;
char w[N][N];
int n,T;
int main(){
cin>>T;
while(T--){
map<char,int>S;
for(int i=1;i<=3;i++){
for(int j=1;j<=3;j++){
cin>>w[i][j];
if(w[i][j]!='?')
S[w[i][j]]++;
}
}
for(auto& [v,w]:S){
if(w!=3){
cout<<v<<endl;
break;
}
}
}
return 0;
}
C. Can I Square?
题面翻译
t t t 组数据。每次给出 n n n 个整数 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n a1,a2,...,an。判断这 n n n 个数的和是否为完全平方数。
translated by @coderJerry
题目描述
Calin has $ n $ buckets, the $ i $ -th of which contains $ a_i $ wooden squares of side length $ 1 $ .
Can Calin build a square using all the given squares?
输入格式
The first line contains a single integer $ t $ ( $ 1 \leq t \leq 10^4 $ ) — the number of test cases.
The first line of each test case contains a single integer $ n $ ( $ 1 \leq n \leq 2 \cdot 10^5 $ ) — the number of buckets.
The second line of each test case contains $ n $ integers $ a_1, \ldots, a_n $ ( $ 1 \leq a_i \leq 10^9 $ ) — the number of squares in each bucket.
The sum of $ n $ over all test cases does not exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case, output “YES” if Calin can build a square using all of the given $ 1 \times 1 $ squares, and “NO” otherwise.
You can output the answer in any case (for example, the strings “yEs”, “yes”, “Yes” and “YES” will be recognized as a positive answer).
样例 #1
样例输入 #1
5
1
9
2
14 2
7
1 2 3 4 5 6 7
6
1 3 5 7 9 11
4
2 2 2 2
样例输出 #1
YES
YES
NO
YES
NO
提示
In the first test case, Calin can build a $ 3 \times 3 $ square.
In the second test case, Calin can build a $ 4 \times 4 $ square.
In the third test case, Calin cannot build a square using all the given squares.
思路
- 注意一下就是:我们这边判断一个数是否是完全平方数,我们就用
sqrt
一下然后看一般的sqrt
和强转成int
的值是否一致,如果一致,就是完全平方数了。
#include<iostream>
#include<cmath>
#define int long long
using namespace std;
const int N = 2e5+10;
int w[N];
int T,n;
signed main(){
cin>>T;
while(T--){
cin>>n;
double res=0;
for(int i=1;i<=n;i++)cin>>w[i],res+=w[i];
if(sqrt(res)==(int)sqrt(res)){
puts("YES");
}else puts("NO");
}
return 0;
}
D. Unnatural Language Processing
题面翻译
卢拉觉得无聊,决定用五个字母 a \texttt{a} a 、 b \texttt{b} b 、 c \texttt{c} c 、 d \texttt{d} d 、 e \texttt{e} e 制作一种简单的语言。字母有两种:
- 元音–字母 a \texttt{a} a 和 e \texttt{e} e 。它们用 V \textsf{V} V 表示。
- 辅音–字母 b \texttt{b} b 、 c \texttt{c} c 和 d \texttt{d} d 。用 C \textsf{C} C 表示。
该语言有两种音节: CV \textsf{CV} CV (辅音后有元音)或 CVC \textsf{CVC} CVC(元音前后有辅音)。例如, ba \texttt{ba} ba 、 ced \texttt{ced} ced 、 bab \texttt{bab} bab 是音节,但 aa \texttt{aa} aa 、 eda \texttt{eda} eda 、 baba \texttt{baba} baba 不是。
语言中的单词是一串音节。Lura 用语言写了一个单词,但她不知道如何将其拆分成音节。帮她把这个词拆成音节。
例如,给定单词 bacedbab \texttt{bacedbab} bacedbab ,它可以拆分成 ba.ced.bab \texttt{ba.ced.bab} ba.ced.bab 音节。(点 . \texttt{.} . 代表音节边界)。
输入
输入由多个测试用例组成。第一行包含一个整数 t t t( 1 ≤ t ≤ 100 1 \leq t \leq 100 1≤t≤100)测试用例的数量。测试用例说明如下。
每个测试用例的第一行包含一个整数 n n n ( 1 ≤ n ≤ 2 ⋅ 1 0 5 1 \leq n \leq 2 \cdot 10^5 1≤n≤2⋅105 ) - 词的长度。
每个测试用例的第二行包含一个由 n n n 个小写拉丁字符组成的字符串–单词。
给出的所有单词都是有效的语言单词;也就是说,它们只使用字母 a \texttt{a} a 、 b \texttt{b} b 、 c \texttt{c} c 、 d \texttt{d} d 、 e \texttt{e} e ,并且每个单词都由多个音节组成。
所有测试用例的 n n n 之和不超过 2 ⋅ 1 0 5 2 \cdot 10^5 2⋅105 。
输出
对于测试用例,输出一个字符串,表示通过在每对相邻音节之间插入一个点 . \texttt{.} . 将单词拆分成音节。
如果存在多种可能的拆分,则输出其中任何一种。输入保证至少存在一种可能的拆分。
题目描述
Lura was bored and decided to make a simple language using the five letters $ \texttt{a} $ , $ \texttt{b} $ , $ \texttt{c} $ , $ \texttt{d} $ , $ \texttt{e} $ . There are two types of letters:
- vowels — the letters $ \texttt{a} $ and $ \texttt{e} $ . They are represented by $ \textsf{V} $ .
- consonants — the letters $ \texttt{b} $ , $ \texttt{c} $ , and $ \texttt{d} $ . They are represented by $ \textsf{C} $ .
There are two types of syllables in the language: $ \textsf{CV} $ (consonant followed by vowel) or $ \textsf{CVC} $ (vowel with consonant before and after). For example, $ \texttt{ba} $ , $ \texttt{ced} $ , $ \texttt{bab} $ are syllables, but $ \texttt{aa} $ , $ \texttt{eda} $ , $ \texttt{baba} $ are not.A word in the language is a sequence of syllables. Lura has written a word in the language, but she doesn’t know how to split it into syllables. Help her break the word into syllables.
For example, given the word $ \texttt{bacedbab} $ , it would be split into syllables as $ \texttt{ba.ced.bab} $ (the dot $ \texttt{.} $ represents a syllable boundary).
输入格式
The input consists of multiple test cases. The first line contains an integer $ t $ ( $ 1 \leq t \leq 100 $ ) — the number of test cases. The description of the test cases follows.
The first line of each test case contains an integer $ n $ ( $ 1 \leq n \leq 2 \cdot 10^5 $ ) — the length of the word.
The second line of each test case contains a string consisting of $ n $ lowercase Latin characters — the word.
All words given are valid words in the language; that is, they only use the letters $ \texttt{a} $ , $ \texttt{b} $ , $ \texttt{c} $ , $ \texttt{d} $ , $ \texttt{e} $ , and each word is made up of several syllables.
The sum of $ n $ over all test cases does not exceed $ 2 \cdot 10^5 $ .
输出格式
For test case, output a string denoting the word split into syllables by inserting a dot $ \texttt{.} $ between every pair of adjacent syllables.
If there are multiple possible splittings, output any of them. The input is given in such a way that at least one possible splitting exists.
样例 #1
样例输入 #1
6
8
bacedbab
4
baba
13
daddecabeddad
3
dac
6
dacdac
22
dababbabababbabbababba
样例输出 #1
ba.ced.bab
ba.ba
dad.de.ca.bed.dad
dac
dac.dac
da.bab.ba.ba.bab.bab.ba.bab.ba
思路
本道题就直接模拟即可,要特别注意一个的情况,忘了这个情况调了半个小时。
#include<iostream>
#include<map>
using namespace std;
const int N = 2e5+10;
string a;
int T;
int n;
int main(){
cin>>T;
while(T--){
cin>>n>>a;
char b[N]={0};
string k;
for(int i=0;i<n;i++){
b[i]=(a[i]=='a'||a[i]=='e'?'V':'C');
}
if(n==1){
cout<<a<<endl;
continue;
}
for(int i=0;i<n;i++){
if(b[i]=='C'){
if(b[i+1]=='V'&&b[i+2]=='C'&&(b[i+3]=='C'||b[i+3]==0)){
k+=a[i];
k+=a[i+1];
k+=a[i+2];
k+=".";
i+=2;
}else if(b[i+1]=='V'&&(b[i+2]=='C'||b[i+2]==0)){
k+=a[i];
k+=a[i+1];
k+=".";
i++;
}
}
}
if(k[k.size()-1]=='.')k.pop_back();
cout<<k;
puts("");
}
return 0;
}
E. Romantic Glasses
题面翻译
第一行输入 t t t,表示有 t t t 组数据。
接下来每组数据先输入数组长度 n n n,接着输入长度为 n n n 的数组 a a a。
求是否存在
L
L
L 和 $ R$,使
a
L
a_L
aL 到
a
R
a_R
aR 中奇数下标的数之和等于偶数下标的数之和,如果存在输出 Yes
,否则输出 No
。
题目描述
Iulia has $ n $ glasses arranged in a line. The $ i $ -th glass has $ a_i $ units of juice in it. Iulia drinks only from odd-numbered glasses, while her date drinks only from even-numbered glasses.
To impress her date, Iulia wants to find a contiguous subarray of these glasses such that both Iulia and her date will have the same amount of juice in total if only the glasses in this subarray are considered. Please help her to do that.
More formally, find out if there exists two indices $ l $ , $ r $ such that $ 1 \leq l \leq r \leq n $ , and $ a_l + a_{l + 2} + a_{l + 4} + \dots + a_{r} = a_{l + 1} + a_{l + 3} + \dots + a_{r-1} $ if $ l $ and $ r $ have the same parity and $ a_l + a_{l + 2} + a_{l + 4} + \dots + a_{r - 1} = a_{l + 1} + a_{l + 3} + \dots + a_{r} $ otherwise.
输入格式
The first line contains a single integer $ t $ ( $ 1 \leq t \leq 10^4 $ ) — the number of test cases.
The first line of each test case contains a single integer $ n $ ( $ 1 \leq n \leq 2 \cdot 10^5 $ ) — the total number of glasses.
The second line of each test case contains $ n $ integers $ a_1, \ldots, a_n $ ( $ 1 \leq a_i \leq 10^9 $ ) — the amount of juice in each glass.
The sum of $ n $ over all test cases does not exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case, output “YES” if there exists a subarray satisfying the condition, and “NO” otherwise.
You can output the answer in any case (for example, the strings “yEs”, “yes”, “Yes” and “YES” will be recognized as a positive answer).
样例 #1
样例输入 #1
6
3
1 3 2
6
1 1 1 1 1 1
10
1 6 9 8 55 3 14 2 7 2
8
1 2 11 4 1 5 1 2
6
2 6 1 5 7 8
9
2 5 10 4 4 9 6 7 8
样例输出 #1
YES
YES
NO
YES
NO
YES
提示
In the first test case, Iulia can pick $ l=1 $ and $ r=3 $ . Then she drinks $ a_1+a_3=1+2=3 $ units and her date drinks $ a_2=3 $ units of juice.
In the second test case, Iulia can pick $ l=2 $ and $ r=5 $ . Then she drinks $ a_3+a_5=1+1=2 $ units and her date drinks $ a_2+a_4=1+1=2 $ units of juice.
In the third test case no such contiguous subarray works.
In the fourth test case, Iulia can pick $ l=2 $ and $ r=8 $ . Then she drinks $ a_3+a_5+a_7=11+1+1=13 $ units and her date drinks $ a_2+a_4+a_6+a_8=2+4+5+2=13 $ units of juice.
思路
这道题千万别被题目骗到了,骑士你把那个等式全部移到同一边发现,我们最终求得就是奇数或偶数同项相减是否有一样的值:
是否存在 L , R ∈ [ 1 , n ] L,R\in[1,n] L,R∈[1,n],使得 s u m 0 , R − s u m 0 , L = s u m 1 , R − s u m 1 , L sum_{0,R}-sum_{0,L}=sum_{1,R}-sum_{1,L} sum0,R−sum0,L=sum1,R−sum1,L。
把等式两边移一下项,就成了 s u m 0 , R − s u m 1 , R = s u m 0 , L − s u m 1 , L sum_{0,R}-sum_{1,R}=sum_{0,L}-sum_{1,L} sum0,R−sum1,R=sum0,L−sum1,L。
显然,最多只存在 n n n 个不同的 s u m 0 , L − s u m 1 , L sum_{0,L}-sum_{1,L} sum0,L−sum1,L。
其中 0 0 0 是奇数, 1 1 1 是偶数。如果有的话,我们就找到了。
- 注意:这边要给我们的
map
容器的0
设为1
,为什么呢?因为0
一定是能被凑出来的(因为 l = r l=r l=r 的)
#include<iostream>
#include<algorithm>
#include<map>
#define int long long
using namespace std;
const int N = 2e5+10;
int w[N];
int n,T;
int s1[N],s2[N];
signed main(){
cin>>T;
while(T--){
cin>>n;
map<int,int>S;
S[0]=1;
for(int i=1;i<=n;i++){
cin>>w[i];
s1[i]=s1[i-1];
s2[i]=s2[i-1];
if(i&1){
s1[i]+=w[i];
}else{
s2[i]+=w[i];
}
}
bool f=false;
for(int i=1;i<=n;i++){
if(S[s1[i]-s2[i]]){
f=true;
break;
}else{
S[s1[i]-s2[i]]=1;
}
}
if(f)puts("YES");
else puts("NO");
}
return 0;
}
F. Greetings
题面翻译
在数轴上有 n n n个人,第 i i i个人位于点 a i a_i ai,想要到达点 b i b_i bi。对于每个人, a i < b i a_i<b_i ai<bi,并且所有人的起点和终点都是不同的。(也就是说,所有的 2 n 2n 2n个数 a 1 , a 2 , … , a n , b 1 , b 2 , … , b n a_1, a_2, \dots, a_n, b_1, b_2, \dots, b_n a1,a2,…,an,b1,b2,…,bn都是不同的。)
所有人将以每秒1单位的速度同时开始移动,直到到达他们的最终点 b i b_i bi。当两个人在同一个点相遇时,他们将互相问候一次。(即使一个人已经到达了最终点,他仍然可以向其他人问候。)
求出将会有多少次问候?
By @dqw
题目描述
There are $ n $ people on the number line; the $ i $ -th person is at point $ a_i $ and wants to go to point $ b_i $ . For each person, $ a_i < b_i $ , and the starting and ending points of all people are distinct. (That is, all of the $ 2n $ numbers $ a_1, a_2, \dots, a_n, b_1, b_2, \dots, b_n $ are distinct.)
All the people will start moving simultaneously at a speed of $ 1 $ unit per second until they reach their final point $ b_i $ . When two people meet at the same point, they will greet each other once. How many greetings will there be?
Note that a person can still greet other people even if they have reached their final point.
输入格式
The first line of the input contains a single integer $ t $ ( $ 1 \le t \le 10^4 $ ) — the number of test cases. The description of test cases follows.
The first line of each test case contains a single integer $ n $ ( $ 1 \le n \le 2 \cdot 10^5 $ ) — the number of people.
Then $ n $ lines follow, the $ i $ -th of which contains two integers $ a_i $ and $ b_i $ ( $ -10^9 \leq a_i < b_i \leq 10^9 $ ) — the starting and ending positions of each person.
For each test case, all of the $ 2n $ numbers $ a_1, a_2, \dots, a_n, b_1, b_2, \dots, b_n $ are distinct.
The sum of $ n $ over all test cases does not exceed $ 2 \cdot 10^5 $ .
输出格式
For each test case, output a single integer denoting the number of greetings that will happen.
样例 #1
样例输入 #1
5
2
2 3
1 4
6
2 6
3 9
4 5
1 8
7 10
-2 100
4
-10 10
-5 5
-12 12
-13 13
5
-4 9
-2 5
3 4
6 7
8 10
4
1 2
3 4
5 6
7 8
样例输出 #1
1
9
6
4
0
提示
In the first test case, the two people will meet at point $ 3 $ and greet each other.
思路
这道题就是通过画图可以知道:
-
首先,容易发现每个人在行进过程中不会追上其他任何一个人,
-
其次,因此一对人 i , j i,j i,j 会问候当且仅当 y i > y j y_i>y_j yi>yj,这时 i i i 会在 y j y_j yj 处问候 j j j。
通过以上两个性质,我们给 x x x 也就是左端点进行排序,此时相遇次数就是逆序对个数。
//逆序对
#include<iostream>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int N = 2e5+10;
struct E{
int a,b;
bool operator<(const E& t)const{
return a<t.a;
}
}e[N];
int w[N],b[N];
int res;
int T,n,m;
void mmsort(int l,int r){
if(l==r)return;
int x=(l+r)>>1;
mmsort(l,x);
mmsort(x+1,r);
int i=l,j=x+1,k=l;
while(i<=x&&j<=r){
if(w[i]<=w[j])b[k++]=w[i++];
else b[k++]=w[j++],m+=x-i+1;
}
while(i<=x)b[k++]=w[i++];
while(j<=r)b[k++]=w[j++];
for(int i=l;i<=r;i++){
w[i]=b[i];
}
}
signed main(){
cin>>T;
while(T--){
cin>>n;
m=0;
for(int i=1;i<=n;i++){
cin>>e[i].a>>e[i].b;
}
sort(e+1,e+1+n);
for(int i=1;i<=n;i++){
w[i]=e[i].b;
}
mmsort(1,n);
cout<<m<<endl;
}
return 0;
}
G. Bicycles
题面翻译
题目描述
给定 n n n 个城市和 m m m 条连接两个城市 u i u_i ui 和 v i v_i vi 的双向道路,长度为 w i w_i wi。
现在城市 n n n 举办了一场派对,住在城市 1 1 1 的 Slavic 想要去参加。在城市之间往返需要骑自行车,而 Slavic 没有自行车,所以他需要在这些城市里购买自行车以赶到城市 n n n。
从 1 1 1 到 n n n 的每个城市 j j j 里都有且仅有一辆自行车可供购买,每辆自行车的速度系数为 s j s_j sj。
当 Slavic 骑上编号为 j j j 的自行车后,他可以在任何时刻和任何地点通过一条道路 i i i,花费 w i × s j w_i\times s_j wi×sj 的时间。
求 Slavic 骑车从城市 1 1 1 赶到城市 n n n 参加派对所需的最短时间。
输入格式
第一行包含一个整数 $ t, ( 1 \leq t \leq 100 )$,代表测试数据组数。
每组数据的第一行包含两个整数 n n n 和 m m m,代表城市的数量和道路的数量。
接下来的 m m m 行中,第 i i i 行包含三个整数 u i u_i ui、 v i v_i vi 和 w i w_i wi,代表一条连接城市 u i u_i ui 和 v i v_i vi,长度为 w i w_i wi 的双向道路。
每组数据的最后一行包含 n n n 个整数 $ s_1, \ldots, s_n $,代表在城市 i i i 可供购买的自行车的速度系数。
输出格式
对于每组测试数据,输出一个整数,代表从城市 1 1 1 到达城市 n n n 所需的最短时间。
数据范围
$ 2 \leq n \leq 1000 , , , n - 1 \leq m \leq 1000 , , , 1 \leq s_i \leq 1000 $;
$ 1 \le u_i, v_i \le n $ , $ u_i \neq v_i , , , 1 \leq w_i \leq 10^5$;
所有测试数据的 ∑ n \sum n ∑n、 ∑ m \sum m ∑m 不超过 1000 1000 1000。
保证存在方案能从城市 1 1 1 到达城市 n n n。
By Misaka16172
题目描述
All of Slavic’s friends are planning to travel from the place where they live to a party using their bikes. And they all have a bike except Slavic. There are $ n $ cities through which they can travel. They all live in the city $ 1 $ and want to go to the party located in the city $ n $ . The map of cities can be seen as an undirected graph with $ n $ nodes and $ m $ edges. Edge $ i $ connects cities $ u_i $ and $ v_i $ and has a length of $ w_i $ .
Slavic doesn’t have a bike, but what he has is money. Every city has exactly one bike for sale. The bike in the $ i $ -th city has a slowness factor of $ s_{i} $ . Once Slavic buys a bike, he can use it whenever to travel from the city he is currently in to any neighboring city, by taking $ w_i \cdot s_j $ time, considering he is traversing edge $ i $ using a bike $ j $ he owns.
Slavic can buy as many bikes as he wants as money isn’t a problem for him. Since Slavic hates traveling by bike, he wants to get from his place to the party in the shortest amount of time possible. And, since his informatics skills are quite rusty, he asks you for help.
What’s the shortest amount of time required for Slavic to travel from city $ 1 $ to city $ n $ ? Slavic can’t travel without a bike. It is guaranteed that it is possible for Slavic to travel from city $ 1 $ to any other city.
输入格式
The first line contains a single integer $ t $ ( $ 1 \leq t \leq 100 $ ) — the number of test cases. The description of the test cases follows.
The first line of each test case contains two space-separated integers $ n $ and $ m $ ( $ 2 \leq n \leq 1000 $ ; $ n - 1 \leq m \leq 1000 $ ) — the number of cities and the number of roads, respectively.
The $ i $ -th of the following $ m $ lines each contain three integers $ u_i $ , $ v_i $ , $ w_i $ ( $ 1 \le u_i, v_i \le n $ , $ u_i \neq v_i $ ; $ 1 \leq w_i \leq 10^5 $ ), denoting that there is a road between cities $ u_i $ and $ v_i $ of length $ w_i $ . The same pair of cities can be connected by more than one road.
The next line contains $ n $ integers $ s_1, \ldots, s_n $ ( $ 1 \leq s_i \leq 1000 $ ) — the slowness factor of each bike.
The sum of $ n $ over all test cases does not exceed $ 1000 $ , and the sum of $ m $ over all test cases does not exceed $ 1000 $ .
Additional constraint on the input: it is possible to travel from city $ 1 $ to any other city.
输出格式
For each test case, output a single integer denoting the shortest amount of time Slavic can reach city $ n $ starting from city $ 1 $ .
样例 #1
样例输入 #1
3
5 5
1 2 2
3 2 1
2 4 5
2 5 7
4 5 1
5 2 1 3 3
5 10
1 2 5
1 3 5
1 4 4
1 5 8
2 3 6
2 4 3
2 5 2
3 4 1
3 5 8
4 5 2
7 2 8 4 1
7 10
3 2 8
2 1 4
2 5 7
2 6 4
7 1 2
4 3 5
6 4 2
6 7 1
6 7 4
4 5 9
7 6 5 4 3 2 1
样例输出 #1
19
36
14
思路
根据题目,我们可以发现一些性质:
- 本道题要求最短路,这个肯定的,我们可以用
dijistra
。 - 其次,这道题它可以买车用新的,也可以用之前骑的,这两者之分就是速度之分。因此我们要对
dijistra
进行改造,比如dist
数组,应该多开一维,存储速度,其他的都必须开一维度。
那么此时代码就很好写了:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#define int long long
using namespace std;
const int N = 1010,M = 2*N;
int T,n,m;
int e[M],ne[M],w[M],s[M],h[N],idx;
bool st[N][N];
int dist[N][N];
struct E{
int x,y,s;
bool operator<(const E& t)const{
return x>t.x;
}
};
void add(int a,int b,int c){
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void dijistra(){
priority_queue<E>q;
dist[1][s[1]]=0;
q.push({0,1,s[1]});
while(q.size()){
int ver=q.top().y;
int sp=q.top().s;
q.pop();
if(st[ver][sp])continue;
st[ver][sp]=true;
for(int i=h[ver];~i;i=ne[i]){
int j=e[i];
if(dist[j][sp]>dist[ver][sp]+w[i]*sp){
dist[j][sp]=dist[ver][sp]+w[i]*sp;
q.push({dist[j][sp],j,sp});
}
if(dist[j][s[j]]>dist[ver][sp]+w[i]*sp){
dist[j][s[j]]=dist[ver][sp]+w[i]*sp;
q.push({dist[j][s[j]],j,s[j]});
}
}
}
}
signed main(){
cin>>T;
while(T--){
memset(h,-1,sizeof h);
memset(st,0,sizeof st);
memset(dist,0x3f,sizeof dist);
idx=0;
cin>>n>>m;
for(int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
add(a,b,c);
add(b,a,c);
}
for(int i=1;i<=n;i++){
cin>>s[i];
}
dijistra();
int res=1e18;
for(int i=1;i<=n;i++){
res=min(res,dist[n][s[i]]);
}
cout<<res<<endl;
}
return 0;
}