Codeforces Gym 101142 C. CodeCoder vs TopForces(思维+图论)

时间:2023-03-09 21:28:28
Codeforces Gym 101142 C. CodeCoder vs TopForces(思维+图论)

题意:

每个人有两个积分CC和TF

第i个人能战胜第j个人的条件满足下面两个条件中的一个即可

1、CCi > CCj 或 TFi > TFj

2、i能战胜k,k能战胜j。

题解:

先按CCi的积分排序,然后连接相邻的两个人a->b,代表a能战胜b

再按TFi的积分排序,做同样的处理。

最后我们按TFi的排序做dfs,只需要dfs一遍就可以得到所有的答案

#include <algorithm>
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
const int maxn = 1e5 + ;
struct Data{
int x, y, id, ans;
}a[maxn];
bool cmp1(const Data& A, const Data& B) { return A.x < B.x; }
bool cmp2(const Data& A, const Data& B) { return A.y < B.y; }
bool cmp3(const Data& A, const Data& B) { return A.id < B.id; }
int vis[maxn];
vector<int> G[maxn];
int n, ans;
void dfs(int x){
if(!vis[x]) ans++;
vis[x] = ;
for(int i = ; i < G[x].size(); i++){
if(vis[G[x][i]]) continue;
dfs(G[x][i]);
}
} int main(){
freopen("codecoder.in", "r", stdin);
freopen("codecoder.out", "w", stdout);
cin>>n;
for(int i = ; i <= n; i++){
cin>>a[i].x>>a[i].y;
a[i].id = i;
}
sort(a+, a++n, cmp1);
for(int i = ; i <= n; i++) G[a[i].id].push_back(a[i-].id);
sort(a+, a++n, cmp2);
for(int i = ; i <= n; i++) G[a[i].id].push_back(a[i-].id);
ans = ;
for(int i = ; i <= n; i++){
dfs(a[i].id);
a[i].ans = ans-;
}
sort(a+, a++n, cmp3);
for(int i = ; i <= n; i++) cout<<a[i].ans<<endl;
}