Codeforces Round 898 (Div. 4)解题

Short Sort

题面翻译

一个字符串由 abc三个字符组成,一次操作可以将两个字符交换,问能否在一次操作以内将字符串变为 abc

By @Larryyu

题目描述

There are three cards with letters $ \texttt{a} $ , $ \texttt{b} $ , $ \texttt{c} $ placed in a row in some order. You can do the following operation at most once:

  • Pick two cards, and swap them.

Is it possible that the row becomes $ \texttt{abc} $ after the operation? Output “YES” if it is possible, and “NO” otherwise.

输入格式

The first line contains a single integer $ t $ ( $ 1 \leq t \leq 6 $ ) — the number of test cases.

The only line of each test case contains a single string consisting of each of the three characters $ \texttt{a} $ , $ \texttt{b} $ , and $ \texttt{c} $ exactly once, representing the cards.

输出格式

For each test case, output “YES” if you can make the row $ \texttt{abc} $ with at most one operation, or “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
abc
acb
bac
bca
cab
cba

样例输出 #1

YES
YES
YES
NO
NO
YES

提示

In the first test case, we don’t need to do any operations, since the row is already $ \texttt{abc} $ .

In the second test case, we can swap $ \texttt{c} $ and $ \texttt{b} $ : $ \texttt{acb} \to \texttt{abc} $ .

In the third test case, we can swap $ \texttt{b} $ and $ \texttt{a} $ : $ \texttt{bac} \to \texttt{abc} $ .

In the fourth test case, it is impossible to make $ \texttt{abc} $ using at most one operation.‘’

代码

#include<iostream>

using namespace std;

char s[50];

int T;
//

int main(){
    cin>>T;
    
    while(T--){
        cin>>s;
        
        if(s[0]=='a'){
            puts("YES");
        }else if(s[0]=='b'&&s[1]=='a'){
            puts("YES");
        }else if(s[0]=='c'&&s[2]=='a'){
            puts("YES");
        }else{
            puts("NO");
            
        }
    }
    return 0;
}

Good Kid

题面翻译

t t t 组数据,每次输入一个 n n n,和一个长度为 n n n 的数组 a a a

问将其中一个数字加 1 1 1 后数组 a a a 内的 n n n 个数的乘积最大是多少?

1 ≤ t ≤ 1 0 4 , 1 ≤ n ≤ 9 , 0 ≤ a i ≤ 9 1 \le t \le 10^4 ,1\le n\le9,0\le a_i \le 9 1t104,1n9,0ai9

题目描述

Slavic is preparing a present for a friend’s birthday. He has an array $ a $ of $ n $ digits and the present will be the product of all these digits. Because Slavic is a good kid who wants to make the biggest product possible, he wants to add $ 1 $ to exactly one of his digits.

What is the maximum product Slavic can make?

输入格式

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 9 $ ) — the number of digits.

The second line of each test case contains $ n $ space-separated integers $ a_i $ ( $ 0 \leq a_i \leq 9 $ ) — the digits in the array.

输出格式

For each test case, output a single integer — the maximum product Slavic can make, by adding $ 1 $ to exactly one of his digits.

样例 #1

样例输入 #1

4
4
2 2 1 2
3
0 1 2
5
4 3 2 3 4
9
9 9 9 9 9 9 9 9 9

样例输出 #1

16
2
432
430467210

代码

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 15;

int T;
int w[N];
int n;

int main(){
    cin>>T;
    
    while(T--){
        cin>>n;
        
        for(int i=1;i<=n;i++){
            cin>>w[i];
        }
        
        sort(w+1,w+1+n);
        
        int res=0;
        for(int i=1;i<=n;i++){
            int cnt=1;
            for(int j=1;j<=n;j++){
                if(i==j)continue;
                cnt*=w[j];
            }
            cnt*=(w[i]+1);
            res=max(res,cnt);
        }
        
        cout<<res<<endl;
    }
    
    return 0;
}

Target Practice

题面翻译

有一个 10 × 10 10\times10 10×10 的标靶,最外环为 1 1 1 分,其次是 2 2 2 分,依此类推,最内环是 5 5 5 分。

给定一个 10 × 10 10\times 10 10×10 的矩阵 s s s,如果 s i , j s_{i,j} si,jX,说明射中了靶标上的 ( i , j ) (i,j) (i,j) ,求总得分。

T T T 组数据。

By @Larryyu

题目描述

A $ 10 \times 10 $ target is made out of five “rings” as shown. Each ring has a different point value: the outermost ring — 1 point, the next ring — 2 points, …, the center ring — 5 points.

Vlad fired several arrows at the target. Help him determine how many points he got.

输入格式

The input consists of multiple test cases. The first line of the input contains a single integer $ t $ ( $ 1 \leq t \leq 1000 $ ) — the number of test cases.

Each test case consists of 10 lines, each containing 10 characters. Each character in the grid is either $ \texttt{X} $ (representing an arrow) or $ \texttt{.} $ (representing no arrow).

输出格式

For each test case, output a single integer — the total number of points of the arrows.

样例 #1

样例输入 #1

4
X.........
..........
.......X..
.....X....
......X...
..........
.........X
..X.......
..........
.........X
..........
..........
..........
..........
..........
..........
..........
..........
..........
..........
..........
..........
..........
..........
....X.....
..........
..........
..........
..........
..........
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX
XXXXXXXXXX

样例输出 #1

17
0
5
220

提示

In the first test case, there are three arrows on the outer ring worth 1 point each, two arrows on the ring worth 3 points each, and two arrows on the ring worth 4 points each. The total score is $ 3 \times 1 + 2 \times 3 + 2 \times 4 = 17 $ .

In the second test case, there aren’t any arrows, so the score is $ 0 $ .

代码

#include<iostream>

using namespace std;

const int N = 15;

char w[N][N];
int T;
int n=10;

int check(int x,int y){
    int cnt=0;
    
    if(x==1||x==10){
        cnt++;
    }else if(x==2||x==9){
        if(y==1||y==10)cnt++;
        else{
            cnt+=2;
        }
    }else if(x==3||x==8){
        if(y==1||y==10)cnt++;
        else if(y==2||y==9)cnt+=2;
        else cnt+=3;
    }else if(x==4||x==7){
        if(y==1||y==10)cnt++;
        else if(y==2||y==9)cnt+=2;
        else if(y==3||y==8)cnt+=3;
        else cnt+=4;
    }else if(x==5||x==6){
        if(y==1||y==10)cnt++;
        else if(y==2||y==9)cnt+=2;
        else if(y==3||y==8)cnt+=3;
        else if(y==4||y==7)cnt+=4;
        else cnt+=5;
    }
    
    return cnt;
}

int main(){
    cin>>T;
    
    while(T--){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                cin>>w[i][j];
            }
        }
        
        int res=0;
        
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(w[i][j]=='X'){
                    res+=check(i,j);
                }
            }
        }
        
        cout<<res<<endl;
        
    }
    return 0;
}

1D Eraser

题面翻译

n n n 个格子,每个格子有一个颜色,W代表白色,B代表黑色。每次可以将连续 k k k 个格子涂白,问最少需要涂多少次才能使所有格子都是白色。

By @Larryyu

题目描述

You are given a strip of paper $ s $ that is $ n $ cells long. Each cell is either black or white. In an operation you can take any $ k $ consecutive cells and make them all white.

Find the minimum number of operations needed to remove all black cells.

输入格式

The first line contains a single integer $ t $ ( $ 1 \leq t \leq 1000 $ ) — the number of test cases.

The first line of each test case contains two integers $ n $ and $ k $ ( $ 1 \leq k \leq n \leq 2 \cdot 10^5 $ ) — the length of the paper and the integer used in the operation.

The second line of each test case contains a string $ s $ of length $ n $ consisting of characters $ \texttt{B} $ (representing a black cell) or $ \texttt{W} $ (representing a white cell).

The sum of $ n $ over all test cases does not exceed $ 2 \cdot 10^5 $ .

输出格式

For each test case, output a single integer — the minimum number of operations needed to remove all black cells.

样例 #1

样例输入 #1

8
6 3
WBWWWB
7 3
WWBWBWW
5 4
BWBWB
5 5
BBBBB
8 2
BWBWBBBB
10 2
WBBWBBWBBW
4 1
BBBB
3 2
WWW

样例输出 #1

2
1
2
1
4
3
4
0

提示

In the first test case you can perform the following operations: $ $KaTeX parse error: Can't use function '$' in math mode at position 101: …texttt{WWWWWW} $̲ $ </p><p>In th…$

思路

我们就贪心的从前往后枚举,可以很容易证明我们的贪心是最优解的。

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 2e5+10;

char w[N];
int n,T,k;
bool st[N];

int main(){
    cin>>T;
    
    
    while(T--){
        cin>>n>>k;
        cin>>(w+1);
        
        int res=0;
        
        for(int i=1;i<=n;i++){
            if(w[i]=='B'){
                i+=k-1;
                res++;
            }
        }
        
        cout<<res<<endl;
        
    }
    return 0;
}

Building an Aquarium

题面翻译

你需要修一个水池,水池的底部高低不一,第 i i i 格高 a i a_i ai

如果修了一个高 h h h 的水池,会先在两侧修高度为 h h h 的墙壁防止水溢出,然后对每一格注水:

  • 对于第 i i i 格,需要向其注水 h − a i h-a_i hai 个单位的水,如果 a i > h a_i>h ai>h,则不用注水。
  • 水可以有剩余,但不能少,少了就无法修建高度为 h h h 的水池。

你一共有 x x x 个单位的水,问 h h h 最大能是多少。

By @Larryyu

题目描述

You love fish, that’s why you have decided to build an aquarium. You have a piece of coral made of $ n $ columns, the $ i $ -th of which is $ a_i $ units tall. Afterwards, you will build a tank around the coral as follows:

  • Pick an integer $ h \geq 1 $ — the height of the tank. Build walls of height $ h $ on either side of the tank.
  • Then, fill the tank up with water so that the height of each column is $ h $ , unless the coral is taller than $ h $ ; then no water should be added to this column.

For example, with $ a=[3,1,2,4,6,2,5] $ and a height of $ h=4 $ , you will end up using a total of $ w=8 $ units of water, as shown. You can use at most $ x $ units of water to fill up the tank, but you want to build the biggest tank possible. What is the largest value of $ h $ you can select?

输入格式

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 two positive integers $ n $ and $ x $ ( $ 1 \leq n \leq 2 \cdot 10^5 $ ; $ 1 \leq x \leq 10^9 $ ) — the number of columns of the coral and the maximum amount of water you can use.

The second line of each test case contains $ n $ space-separated integers $ a_i $ ( $ 1 \leq a_i \leq 10^9 $ ) — the heights of the coral.

The sum of $ n $ over all test cases doesn’t exceed $ 2 \cdot 10^5 $ .

输出格式

For each test case, output a single positive integer $ h $ ( $ h \geq 1 $ ) — the maximum height the tank can have, so you need at most $ x $ units of water to fill up the tank.

We have a proof that under these constraints, such a value of $ h $ always exists.

样例 #1

样例输入 #1

5
7 9
3 1 2 4 6 2 5
3 10
1 1 1
4 1
1 4 3 4
6 1984
2 6 5 9 1 8
1 1000000000
1

样例输出 #1

4
4
2
335
1000000001

提示

The first test case is pictured in the statement. With $ h=4 $ we need $ 8 $ units of water, but if $ h $ is increased to $ 5 $ we need $ 13 $ units of water, which is more than $ x=9 $ . So $ h=4 $ is optimal.

In the second test case, we can pick $ h=4 $ and add $ 3 $ units to each column, using a total of $ 9 $ units of water. It can be shown that this is optimal.

In the third test case, we can pick $ h=2 $ and use all of our water, so it is optimal.

代码(简单二分)

#include<iostream>
#include<algorithm>

#define int long long

using namespace std;

const int N = 2e5+10;

int w[N];
int n,T,k;

bool check(int x){
    
    int cnt=0;
    
    for(int i=1;i<=n;i++){
        cnt+=max(0ll,x-w[i]);
    }
    
    return cnt<=k;
    
}

signed main(){
    cin>>T;
    
    while(T--){
        cin>>n>>k;
        
        for(int i=1;i<=n;i++)cin>>w[i];
        
        int l=-1,r=2e9+1;
        
        while(l+1!=r){
            int mid=l+r>>1;
            if(check(mid))l=mid;
            else r=mid;
        }
        
        cout<<l<<endl;
        
    }
    
    return 0;
    
}

Money Trees

题面翻译

n n n 棵树,每棵树高 h i h_i hi,有 a i a_i ai 个果子。

你可以选一对 l l l r r r,使得 h i + 1 ∣ h i   ( l ≤ i < r ) h_{i+1}\mid h_i\space(l\le i<r) hi+1hi (li<r) a l + a l + 1 + ⋯ + a r ≤ k a_l+a_{l+1}+\dots +a_r\le k al+al+1++ark

r − l + 1 r-l+1 rl+1 的最大值。

By @Larryyu

题目描述

Luca is in front of a row of $ n $ trees. The $ i $ -th tree has $ a_i $ fruit and height $ h_i $ .

He wants to choose a contiguous subarray of the array $ [h_l, h_{l+1}, \dots, h_r] $ such that for each $ i $ ( $ l \leq i < r $ ), $ h_i $ is divisible $ ^{\dagger} $ by $ h_{i+1} $ . He will collect all the fruit from each of the trees in the subarray (that is, he will collect $ a_l + a_{l+1} + \dots + a_r $ fruits). However, if he collects more than $ k $ fruits in total, he will get caught.

What is the maximum length of a subarray Luca can choose so he doesn’t get caught?

$ ^{\dagger} $ $ x $ is divisible by $ y $ if the ratio $ \frac{x}{y} $ is an integer.

输入格式

The first line contains a single integer $ t $ ( $ 1 \leq t \leq 1000 $ ) — the number of test cases.

The first of each test case line contains two space-separated integers $ n $ and $ k $ ( $ 1 \leq n \leq 2 \cdot 10^5 $ ; $ 1 \leq k \leq 10^9 $ ) — the number of trees and the maximum amount of fruits Luca can collect without getting caught.

The second line of each test case contains $ n $ space-separated integers $ a_i $ ( $ 1 \leq a_i \leq 10^4 $ ) — the number of fruits in the $ i $ -th tree.

The third line of each test case contains $ n $ space-separated integers $ h_i $ ( $ 1 \leq h_i \leq 10^9 $ ) — the height of the $ i $ -th tree.

The sum of $ n $ over all test cases does not exceed $ 2 \cdot 10^5 $ .

输出格式

For each test case output a single integer, the length of the maximum length contiguous subarray satisfying the conditions, or $ 0 $ if there is no such subarray.

样例 #1

样例输入 #1

5
5 12
3 2 4 1 8
4 4 2 4 1
4 8
5 4 1 2
6 2 3 1
3 12
7 9 10
2 2 4
1 10
11
1
7 10
2 6 3 1 5 10 6
72 24 24 12 4 4 2

样例输出 #1

3
2
1
0
3

提示

In the first test case, Luca can select the subarray with $ l=1 $ and $ r=3 $ .

In the second test case, Luca can select the subarray with $ l=3 $ and $ r=4 $ .

In the third test case, Luca can select the subarray with $ l=2 $ and $ r=2 $ .

思路(双指针)

我们采取先枚举每个 r r r,就是 r r r 按照顺序进行枚举,然后再枚举的过程中,我们算 h i h_i hi 整除 h i + 1 h_{i+1} hi+1,如果能整除的话,我们就看下那个和是不是大于 k k k,最后我们更新一下答案。如果不能整除,此时就得把 l = r l=r l=r,就是前面的区间不要了,新开一个。

这样, l l l r r r 之间的数就是我们满足条件的了。

//two Point

#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;

const int N = 2e5+10;

int w[N],h[N],s[N];
int T,n,k;

int main(){
    cin>>T;
    
    while(T--){
        cin>>n>>k;
        s[0]=0;
        for(int i=1;i<=n;i++)cin>>w[i],s[i]=s[i-1]+w[i];
        for(int i=1;i<=n;i++)cin>>h[i];
        
        int res=0;
        
        for(int i=1,l=1,r;i<=n;i++){
            r=i;
            if(h[i-1]%h[i])l=r;
            while(s[r]-s[l-1]>k)l++;
            res=max(res,r-l+1);
        }
        
        
        cout<<res<<endl;
        
    }
    return 0;
}

ABBC or BACB

题面翻译

给定一个由 AB组成的字符串 s s s,有两种操作:

  • 将一个子串 AB转换为 BC并获得一枚金币。
  • 将一个字串 BA转换为 CB并获得一枚金币。

你可以进行若干次操作,问最多能获得多少枚金币。

By @Larryyu

题目描述

You are given a string $ s $ made up of characters $ \texttt{A} $ and $ \texttt{B} $ . Initially you have no coins. You can perform two types of operations:

  • Pick a substring $ ^\dagger $ $ \texttt{AB} $ , change it to $ \texttt{BC} $ , and get a coin.
  • Pick a substring $ ^\dagger $ $ \texttt{BA} $ , change it to $ \texttt{CB} $ , and get a coin.

What is the most number of coins you can obtain? $ ^\dagger $ A substring of length $ 2 $ is a sequence of two adjacent characters of a string.

输入格式

The input consists of multiple test cases. The first line of the input contains a single integer $ t $ ( $ 1 \leq t \leq 1000 $ ) — the number of test cases.

The only line of each test case contains the string $ s $ ( $ 1 \leq |s| \leq 2 \cdot 10^5 $ ). All characters of $ s $ are either $ \texttt{A} $ or $ \texttt{B} $ .

The sum of the lengths of $ s $ over all test cases does not exceed $ 2 \cdot 10^5 $ .

输出格式

For each test case, output a single integer — the maximum number of coins you can obtain.

样例 #1

样例输入 #1

8
ABBA
ABA
BAABA
ABB
AAAAAAB
BABA
B
AAA

样例输出 #1

2
1
3
1
6
2
0
0

提示

In the first test case you can perform the following operations to get $ 2 $ coins: $ $KaTeX parse error: Can't use function '$' in math mode at position 95: … \texttt{BCCB} $̲ $ </p><p>In th…$

思路(思维题)

这道题我们就是去发现规律,根据题目,其实就是把 A B AB AB A A A 变成 B B B B B B 变成 C C C

  • 我们发现:如果是 AAAAAAB,那么它是变成 BCCCCCC 了,如果是 AAABAAAA,我们要么将它变成 BCCCAAAA,要么是 AAACCCB,此时就得比较哪个大了。
  • 因此,我们进一步分析,发现: k k kB 可以把整个数组分成 K + 1 K+1 K+1 个区间,其中肯定有 1 个区间是荒废的。(这点可以举例子发现)
  • 那么我们要求整体最大值,那么也就是让 A A A 的总数减去 A A A 连续区间的最小值那么就是最大值:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>

using namespace std;

const int N = 2e5+10;

char s[N];
int T,n;
int w[N];
//B devide k substr,至少有一个区间是舍弃的

int main(){
    cin>>T;
    
    while(T--){
        cin>>(s+1);
        
        n=strlen(s+1);
        
        vector<int>l;
        
        int sum=0,num=0;//A tot_num||constitude A's num
        
        for(int i=1;i<=n;i++){
            if(s[i]=='A')num++,sum++;
            else l.push_back(num),num=0;
        }
        
        l.push_back(num);
        sort(l.begin(),l.end());
        
        cout<<sum-l[0]<<endl;
        
        
    }
    return 0;
}

Mad City

题面翻译

题目描述

Marcel 和 Valeriu 住在一座包含 n n n 座建筑物和 n n n 条无向边的城市。

初始时,Marcel 和 Valeriu 分别处于建筑物 a a a 和建筑物 b b b。 Marcel 想要抓住 Valeriu。Valeriu 被 Marcel 抓住,当且仅当二人在某一时刻处于同一条边或同一座建筑物中。

在每次行动中,他们会选择移动到一个相邻的建筑物中,或停留在原地。由于 Valeriu 十分了解 Marcel,Valeriu 能够预测出 Marcel 的下一步行动。Valeriu 可以利用这些信息来制定行动路线。二人同时开始和结束行动。

对于任何两个建筑物,有且仅有一条路径将二者相连。

假设二人都绝顶聪明,判断 Valeriu 是否能够永远不被 Marcel 抓住。

输入格式

本题有多组测试数据。

第一行包含一个整数 t ( 1 ≤ t ≤ 1000 ) t (1\le t\le 1000) t1t1000,代表测试数据的组数。

对于每组测试数据,第一行包含三个整数 n , a , b ( 3 ≤ n ≤ 2 × 1 0 5 , 1 ≤ a , b ≤ n ) n,a,b(3\le n\le 2\times10^5,1\le a,b\le n) nab3n2×1051abn,分别表示建筑物的数目、Marcel 与 Valeriu 的初始位置。

接下来的 n n n 行,每行包含两个整数 u i , v i ( 1 ≤ u i , v i ≤ n ) u_i,v_i(1 \le u_i,v_i\le n) uivi1uivin,表示存在一条连接建筑物 u u u v v v 的无向边。数据保证不存在自环或重边。

所有测试数据中的 n n n 之和不超过 2 × 1 0 5 2\times 10^5 2×105

数据保证图是联通的。

输出格式

对于每组测试数据,如果 Marce 永远无法追上 Valeriu,在单独的一行中输出 YES,否则输出 NO(输出不区分字母的大小写,例如假设某组测试数据中 Marce 永远无法追上 Valeriu,输出 YesyesYeS 都被视为正确答案)。

题目描述

Marcel and Valeriu are in the mad city, which is represented by $ n $ buildings with $ n $ two-way roads between them.

Marcel and Valeriu start at buildings $ a $ and $ b $ respectively. Marcel wants to catch Valeriu, in other words, be in the same building as him or meet on the same road.

During each move, they choose to go to an adjacent building of their current one or stay in the same building. Because Valeriu knows Marcel so well, Valeriu can predict where Marcel will go in the next move. Valeriu can use this information to make his move. They start and end the move at the same time.

It is guaranteed that any pair of buildings is connected by some path and there is at most one road between any pair of buildings.

Assuming both players play optimally, answer if Valeriu has a strategy to indefinitely escape Marcel.

输入格式

The first line contains a single integer $ t $ ( $ 1 \leq t \leq 1000 $ ) — the number of test cases.

The first line of each test case contains three space-separated integers $ n $ , $ a $ , $ b $ ( $ 3 \leq n \leq 2 \cdot 10^5 $ ; $ 1 \leq a, b \leq n $ ) — the number of buildings (which equals the number of roads) and the starting buildings of Marcel and Valeriu.

The following $ n $ lines each contain two integers $ u_i $ , $ v_i $ ( $ 1 \le u_i, v_i \le n $ , $ u_i \neq v_i $ ) — there is a road between buildings $ u_i $ and $ v_i $ . There is at most one road between any unordered pair of buildings.

The sum of $ n $ over all test cases does not exceed $ 2 \cdot 10^5 $ .

The roads are given that it is possible to get from any building to any other building going along the roads.

输出格式

For each test case output “YES” if Valeriu can escape Marcel forever 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 2 1
2 1
3 2
1 3
4 1 4
1 4
1 2
1 3
2 3
4 1 2
1 2
2 3
2 4
3 4
7 1 1
4 1
2 1
5 3
4 6
4 2
7 5
3 4
8 5 3
8 3
5 1
2 6
6 8
1 2
4 8
5 7
6 7
10 6 1
1 2
4 3
5 8
7 8
10 4
1 9
2 4
8 1
6 2
3 1

样例输出 #1

YES
NO
YES
NO
NO
YES

提示

In the first test case the graph looks as follows:

Marcel starts at building $ 2 $ , while Valeriu starts at building $ 1 $ . Valeriu knows which way Marcel will move around the triangle, and he can simply always move in the same way to avoid Marcel forever.In the second test case the graph looks as follows:

Marcel starts at building $ 1 $ , while Valeriu starts at building $ 4 $ . Marcel can go to building $ 4 $ on his first move and win, since Valeriu must either go to building $ 1 $ (then he meets Marcel on the road from $ 1 $ to $ 4 $ ) or stay at building $ 4 $ (then he meets Marcel at building $ 4 $ ). So there is no strategy for Valeriu to win.

思路

这道题很明显,我们知道,只有 b b b 的位置是在环上,那么 a a a 就永远也抓不到 b b b

但有可能 b b b 不在环上,此时我们肯定是让 b b b 上环最好,因此我们就得计算它离环的最短距离,同时也要算 a a a 离它的最短距离,如果 d i s t [ a ] > d i s t [ b ] dist[a]>dist[b] dist[a]>dist[b],说明 b b b 可以更早的到环上。

  • 根据这一点,我们可以先求出环。——拓扑排序(我们可以在拓扑排序求出离 b b b 最近的环上的点)。
  • 求最短路——dijistra或bfs。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#define x first
#define y second
#define int long long

using namespace std;

const int N = 2e5+10,M = 2*N;

typedef pair<int,int>PII;

int e[M],ne[M],h[N],idx;
int dist[N];
int T;
int n,a,b;
int din[N];
int root;
bool st[N];

void add(int a,int b){
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

void topsort(){
    
    queue<int>q;
    
    for(int i=1;i<=n;i++){
        if(din[i]==1){
            q.push(i);
        }
    }
    
    while(q.size()){
        int t=q.front();
        q.pop();
        
        for(int i=h[t];~i;i=ne[i]){
            int j=e[i];
            --din[j];//
            if((din[j])<=0)continue;//del
            if((din[j])==1)q.push(j);
            if(t==root)root=j;
        }
    }
    
}

void dijistra(int u){
    priority_queue<PII,vector<PII>,greater<PII>>q;
    
    q.push({dist[u],u});
    
    while(q.size()){
        int ver=q.top().y;
        q.pop();
        
        if(st[ver])continue;
        st[ver]=true;
        
        for(int i=h[ver];~i;i=ne[i]){
            int j=e[i];
            if(dist[j]>dist[ver]+1){
                dist[j]=dist[ver]+1;
                q.push({dist[j],j});
            }
        }
    }
}

signed main(){
    cin>>T;
    
    while(T--){
        cin>>n>>a>>b;
        
        memset(h,-1,sizeof h);
        memset(dist,0x3f,sizeof dist);
        memset(st,0,sizeof st);
        memset(din,0,sizeof din);
        idx=0;
        root=b;
        for(int i=1;i<=n;i++){
            int c,d;
            cin>>c>>d;
            add(c,d),add(d,c);
            din[d]++,din[c]++;
        }
        
        if(a==b){
            puts("NO");
            continue;
        }
        
        topsort();
        
        
        if(din[b]>=2){
            puts("YES");
            continue;
        }
        
        // cout<<root<<endl;
        
        dist[root]=0;
        dijistra(root);
        
        if(dist[a]>dist[b])puts("YES");
        else puts("NO");
        
    }
    
    return 0;
}
  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

green qwq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值