CF #481 (div3)F

F. Mentors

description:

给出n个数代表n个人的技能值,之后给出一组关系代表两两人之间有矛盾,问最后对于每个人来说,有多少人和他没矛盾且技能值严格小于他。

input:

第一行n和k分别代表人数和有矛盾的对数。

之后k行每行两个数,代表两个人有矛盾。

output:

从第一个人到第n个人,依次输出符合条件的人数。

analysis:

这一题有两个条件:没矛盾 和 技能值小于当前考虑的人。

如果先考虑第一个条件,就会想到图论上去,在意个图中找出互相不连接,且权值小于当前节点的点的个数。然而,这里用图论还是不合适,因为这里面的关系没有传递性,只是两两之间的关系。先考虑第一个条件很不自然。

换一个角度,先考虑第二个条件,那么就只要对技能值排序,就可以直接根据序号找出有多少人的技能值小于当前的人。剩下的是把有矛盾的从其中去掉,可以通过一个slack数组记录和u矛盾的点中技能值比它小的点的个数,这可以在输入u v矛盾对时直接更新slack.

   if(a[u].first>a[v].first)slack[u]++;
            else if(a[v].first>a[u].first)slack[v]++;

最后在对每个点计算答案即可,由于要求严格小于,所以要用lower_bound找出与当前点相等的最小下标,然后减去(slack+1)就是答案了。具体看代码。

代码:

#include<iostream>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<sstream>
#include<cmath>
#include<iterator>
#include<bitset>
#include<stdio.h>
using namespace std;
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
typedef long long LL;
LL readint() { LL x; scanf("%lld",&x); return x; }
const int INF = 1 << 30;
const int maxn = 200005;
int n,m;
pair<int,int> a[maxn];
int slack[maxn];
int ans[maxn];
int num[maxn];
int main()
{

//	freopen("C:\\Users\\admin\\Desktop\\in.txt", "r", stdin);
//	freopen("C:\\Users\\admin\\Desktop\\out.txt", "w", stdout);
    while(~scanf("%d%d",&n,&m)){
        memset(slack,0,sizeof(slack));
        for(int i=1;i<=n;++i){scanf("%d",&a[i].first);a[i].second=i;}
        while(m--){
            int u,v;scanf("%d%d",&u,&v);
            if(a[u].first>a[v].first)slack[u]++;    //计算slack
            else if(a[v].first>a[u].first)slack[v]++;
        }
        sort(a+1,a+1+n);     
        for(int i=1;i<=n;++i)num[i]=a[i].first;    
        for(int i=1;i<=n;++i){
            int id=a[i].second;
            ans[id]=(lower_bound(num+1,num+1+n,a[i].first)-num)-slack[id]-1;   //计算答案
        }
        for(int i=1;i<=n;++i)printf("%d ",ans[i]);
        printf("\n");
    }

	return 0;
}

猜你喜欢

转载自blog.csdn.net/tomandjake_/article/details/80333184
今日推荐