Gym101142C CodeCoder vs TopForces

题意:有n个人,每一个人有两个分数,只要一个人大于另一个人的一个分数,那么这个人就有可能打败另一个人,(有传递性,比如1,3->10,2, 10,2->9,9那么1,3->9,9)

题解:分别按两种分数排序,那么最大的一定可以打败比他小的所有人,他要打败最多的人,那么只能打败他相邻的人(传递性),那么就是对每个点找最长路,n^2不能过这里可以发现有很多重复的,也就是说当前这个点的能到的点,其父节点也可以到达,所以只要从最小的点开始搜索,标记及答案不清空

#include <bits/stdc++.h>
#define maxn 101000
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
struct node {
    int a, b, c, ans;
}t[maxn];
int sum, dir[maxn];
vector<int>G[maxn];
int cmp1(node aa,node bb){
    return aa.a<bb.a;
}
int cmp2(node aa, node bb){
    return aa.b<bb.b;
}
int cmp3(node aa,node bb){
    return aa.c<bb.c;
}
void dfs(int x){
    sum++;
    dir[x] = 1;
    for(int i=0;i<G[x].size();i++){
        if(dir[G[x][i]] == 0){
            dfs(G[x][i]);
        }
    }
}
int main(){
    int n;
    //freopen("codecoder.in","r",stdin); freopen("codecoder.out","w",stdout);
    scanf("%d", &n);
    for(int i=0;i<n;i++){
        scanf("%d%d", &t[i].a, &t[i].b);
        t[i].c = i;
    }
    sort(t, t+n, cmp1);
    for(int i=n-1;i>0;i--){
        G[t[i].c].push_back(t[i-1].c);
    }
    sort(t, t+n, cmp2);
    for(int i=n-1;i>0;i--){
        G[t[i].c].push_back(t[i-1].c);
    }
    for(int i=0;i<n;i++){
        if(dir[t[i].c] == 0){
            dfs(t[i].c);
        }
        t[i].ans = sum-1;
    }
    sort(t, t+n, cmp3);
    for(int i=0;i<n;i++){
        printf("%d
", t[i].ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Noevon/p/7795500.html