题目链接:

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;
}
posted on 2022-01-25 19:02  Hamine  阅读(106)  评论(0编辑  收藏  举报