题目链接:https://codeforces.com/gym/105924
题目背景:
给定一个二分图,左图编号 1 ~ n,右图 n + 1 ~ 2n,左图的每个城市都会与右图的某个城市犯冲(每个城市都只与一个城市犯冲),除犯冲的城市外,不同侧的城市之间都有道路,给定起点与终点,请问是否可以到达(Yes or No)。
思路:
分类讨论:在同侧,如果 n >= 3,一定有解。n < 3一定无解。在异侧只需判断是否犯冲即可。
eq(同侧):可假设图为上图(连线为犯冲)。如果n = 3,s = 1,t = 2,可行路径就为 1 - 6 - 2,未经过犯冲城市。如果 n = 2,我们怎样走都会经过犯冲城市。
特判:s == t。
数据范围:
n 总和小于 2e5。
时间复杂度:
O(n)
ac代码:
#include <bits/stdc++.h>
#define ioscc ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define endl '\n'
#define me(a, x) memset(a, x, sizeof a)
#define all(a) a.begin(), a.end()
#define sz(a) ((int)(a).size())
#define pb(a) push_back(a)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<vector<int>> vvi;
typedef vector<int> vi;
typedef vector<bool> vb;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
const int MAX = (1ll << 31) - 1;
const int MIN = 1 << 31;
const int MOD = 1e9 + 7;
const int N = 1e5 + 10;
template <class T>
ostream &operator<<(ostream &os, const vector<T> &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cout << a[i] << ' ';
return os;
}
template <class T>
istream &operator>>(istream &in, vector<T> &a) noexcept
{
for (int i = 0; i < sz(a) - 10; i++)
std::cin >> a[i];
return in;
}
/* 有乘就强转,前缀和开ll */
void solve()
{
int n, s, t;
cin >> n >> s >> t;
vi a(n + 10);
for (int i = 1; i <= n; ++i)
cin >> a[i];
if (s == t)
{
cout << "Yes" << endl;
return;
}
if ((s <= n && t <= n) || (s > n && t > n))
{
if (n <= 2)
cout << "No" << endl;
else
cout << "Yes" << endl;
}
else
{
if ((s <= n && a[s] == t) || (t <= n && a[t] == s))
cout << "No" << endl;
else
cout << "Yes" << endl;
}
}
int main()
{
ioscc;
int T;
cin >> T;
while (T--)
solve();
return 0;
}