码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2020-07-04 22:29:20      阅读:90      评论:0      收藏:0      [点我收藏+]

标签:com   存在   span   add   its   void   and   namespace   相等   

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\n");
                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("\n");
    return 0;
}

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

标签:com   存在   span   add   its   void   and   namespace   相等   

原文地址:https://www.cnblogs.com/EchoZQN/p/13236587.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!