题目链接:
https://codeforces.com/problemset/problem/1608/C
题目大意:
\(n\) 个玩家玩一个游戏,游戏中有两个地图,每个玩家在两个地图中的能力值已知,同一个地图中能力值大的玩家可以打赢能力值小的玩家(同一地图中不会出现能力值相同的玩家),现组织一场比赛,进行 \(n\) - 1 场对战,每场对战顺序和地图可以选择,判断哪些玩家可以获胜,输出 1,否则输出 0。
思路:
如果我们将 \(x\) 能战胜 \(y\) 定义为一条 \(x\) 指向 \(y\) 的有向边,那么某个玩家能获胜的条件就是这个点能到达图上所有点。
接下来反过来想,让边反着指,那么就是看地图中有最大能力值的那个点能达到图中哪些点,这些玩家都能够获胜,就是简单的一个搜索。
代码:
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
const int N = 1e5 + 10;
int T = 1, n, ans[N];
pair <int, int> a[N], b[N];
vector <int> e[N];
void bfs(){
queue <int> q;
ans[a[n].se] = ans[b[n].se] = 1; //两个地图中能力值最大的点作为起点
q.push(a[n].se), q.push(b[n].se);
while (q.size()){
int x = q.front(); q.pop();
for (auto &y : e[x]){
if (ans[y]) continue;
ans[y] = 1;
q.push(y);
}
}
}
void solve(){
cin >> n;
for (int i = 1; i <= n; i++){
scanf("%d", &a[i].fi);
a[i].se = i;
e[i].clear();
ans[i] = 0;
}
for (int i = 1; i <= n; i++){
scanf("%d", &b[i].fi);
b[i].se = i;
}
sort(a + 1, a + n + 1);
sort(b + 1, b + n + 1);
for (int i = 1; i < n; i++)
e[a[i].se].push_back(a[i + 1].se);
for (int i = 1; i < n; i++)
e[b[i].se].push_back(b[i + 1].se);
bfs();
for (int i = 1; i <= n; i++)
cout << ans[i];
cout << "\n";
}
int main(){
cin >> T;
while (T--)
solve();
return 0;
}