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;
}
原文地址:https://www.cnblogs.com/Saurus/p/7637391.html