[D. Johnny and Contribution] 思维 暑训第二天

Posted echozqn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[D. Johnny and Contribution] 思维 暑训第二天相关的知识,希望对你有一定的参考价值。

D. Johnny and Contribution

题目:

给你每一个点想要的数字,然后让你给出一种顺序来填数字,使得填完数字后和想要的数字是一样的,这个填数字的要求就是除开相邻的点填的数字之外的最小正整数。

题解:

这个题目太毒瘤了,题意难读懂,读懂之后又感觉很容易弄错,看的我心累。。。

这个贪心的考虑肯定是先填数字小的,所以可以把每个点期望存的数字存在一个结构体里面,然后按照期望数字从小到大的排序,除此之外,还要用一个数组来表示这个数字是不是达到存的要求了,这个时候就可以用一个num数组,首先num数组都初始化为1,表示先填1这个数字,然后每填一个数字如果相邻的点的数字和这个一样则说明这个点应该填更大的一个数字,所以 $num++ $ 。最后判断(num[u] == i) 这个 (i) 表示 (u) 的期望数字,如果两个相等则可以成功填上去,否则就输出 -1。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5+10;
vector<int>G[maxn];
vector<int>v[maxn];
void add(int u,int v){
    G[u].push_back(v);
    G[v].push_back(u);
}
struct node{
    int id,t;
    node(int id=0,int t=0):id(id),t(t){}
}e[maxn];

bool cmp(node a,node b){
    return a.t<b.t;
}
int num[maxn],ans[maxn];
int main(){
    int n,m,now=0;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        add(u,v);
    }
    for(int i=1,t;i<=n;i++){
        scanf("%d",&t);
        e[i]=node(i,t);
        v[t].push_back(i);
        num[i]=1;
    }
    sort(e+1,e+1+n,cmp);
    for(int i=1;i<=n;i++){
        for(int j=0;j<v[i].size();j++){
            int u=v[i][j];
            if(num[u]!=i){
                printf("-1
");
                return 0;
            }
            ans[++now]=u;
            for(int k=0;k<G[u].size();k++){
                int v=G[u][k];
                if(num[v]==i) num[v]++;
            }
        }
    }
    for(int i=1;i<=n;i++) printf("%d ",ans[i]);
    printf("
");
    return 0;
}

以上是关于[D. Johnny and Contribution] 思维 暑训第二天的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #647 (Div. 2) D. Johnny and Contribution(BFS)

Johnny and Grandmaster

Johnny and Grandmaster

E. Johnny and Grandmaster

E. Johnny and Grandmaster

题解 CF1361B Johnny and Grandmaster