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 + 100; 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] = 1; for(int i = 0; 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 = 1; i <= n; i++){ cin>>a[i].x>>a[i].y; a[i].id = i; } sort(a+1, a+1+n, cmp1); for(int i = 2; i <= n; i++) G[a[i].id].push_back(a[i-1].id); sort(a+1, a+1+n, cmp2); for(int i = 2; i <= n; i++) G[a[i].id].push_back(a[i-1].id); ans = 0; for(int i = 1; i <= n; i++){ dfs(a[i].id); a[i].ans = ans-1; } sort(a+1, a+1+n, cmp3); for(int i = 1; i <= n; i++) cout<<a[i].ans<<endl; }