牛客网算法竞赛难题

闲的没事参加了一下牛客网的算法训练赛

才发现这么难(划掉

才发现我对时间和空间复杂度的运算能力这么差

其中有一道题我的代码超过了空间限制

 

 

 而另外一个人的没有。。。

 

 

 还AC了

但是对比我们两个的代码我发现

好像开的数组一样大,我甚至还把一个数组换成了vector,但是还是内存爆掉了

搞不清为什么

原题如下:

糖果

题目描述:

在一个幼儿园里面有n\mathit nn个小朋友,分别编号1,2,...,n\text 1,2,...,n1,2,...,n。在这些小朋友中有一些小朋友互为朋友关系,总共有m\mathit mm对朋友。
作为幼儿园老师,你想买一些糖果分给小朋友,你知道第i\mathit ii个小朋友想要至少aia_{i}ai个糖果,否则他就会不开心。
同时,如果一个小朋友得到的糖果数小于他某个朋友得到的糖果数,他也会不开心。
请问你最少买多少糖果才能保证每个小朋友都不会不开心呢?

链接:https://ac.nowcoder.com/acm/contest/9983/G
来源:牛客网

输入描述:

第一行以空格分隔的两个整数n,m
第二行以空格分隔的n个正整数ai
接下来m行每行以空格分隔的两个正整数u,v,代表uv的朋友,vu的朋友。

输出描述:

购买的最少糖果数以保证每个小朋友都不会不开心。

输入

3 1
1 2 3
1 2

输出

 7

说明

给第三个小朋友买3个糖果,前两个小朋友都买2两个糖果,总共至少买7个糖果。注意如果给第一个小朋友只买了1个糖果,那么他在看到自己的好朋友2有2个糖果的情况下,他就会不开心。

这道题题面上没有说朋友的朋友就是自己朋友

但也不难分析出来

假如A是B的朋友,c是B的朋友

A想要2颗糖,B想要3颗,C想要五颗

为了让C开心,C会得到5颗糖

为了让B开心,B也会得到五颗,因为B是C的朋友,当ta瞅瞅C手中的五颗糖和自己手中的三颗糖时,会很不开心

同理,为了让A开心,也给A五颗糖

A得到的糖数量与C相等

所以说这道题有考到并查集

那么我的代码是这样的:

 1 #include <bits/stdc++.h>
 2 #include <vector>
 3 using namespace std;
 4 int n,m,a,b,sum[1000005],head[1000005],ww;
 5 vector <int> w;
 6 long long ans;//经过计算,我认为ans的值可能会超过int类型
 7 int find(int x){//寻找两拨孩子的头目
 8     if(head[x]!=x)
 9     head[x]=find(x);
10     return head[x];
11 }
12 void hb(int x,int y){//把两拨孩子合并
13     int xx=find(x);
14     int yy=find(y);
15     head[yy]=xx;
16 }
17 int main(){
18     w.push_back(0);
19     cin>>n>>m;
20     for(int i=1;i<=n;i++){
21         head[i]=i;//初始化头领
22         sum[i]=1;//初始化队伍人数
23     }
24     for(int i=1;i<=n;i++){
25         cin>>ww;
26         w.push_back(ww);
27     }
28     for(int i=1;i<=m;i++){
29         cin>>a>>b;
30         if(find(a)!=find(b)){
31             sum[find(a)]+=sum[find(b)];//把两拨人数相加
32             hb(a,b);
33             w[find(a)]=max(w[a],w[b]);//寻找这些人中,想要糖果最多的数量
34         }
35     }
36     for(int i=1;i<=n;i++){
37         if(head[i]==i){//找到每队头领,代表该队即可;
38             ans+=sum[i]*w[i];
39         }
40     }
41     cout<<ans;
42     return 0;
43 }

别人家的代码长这样(注释是根据我自己的理解写的,他才没那么善良

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <vector>
 4 using namespace std;
 5 int fa[1000005];//头目
 6 inline int ff(int x)//相当于我代码里的find函数
 7 {
 8     if(fa[x]==x) return x;
 9     return fa[x]=ff(fa[x]);
10 }
11 int mx[1000005],sz[1000005],a[1000005];
12 int main(int argc, char** argv){ //main函数里加代码我还是第一次见,详情见博客https://blog.csdn.net/hopeneversleep/article/details/55798722
13     int n,m;
14     cin >> n >> m;
15     for(int i=1;i<=n;i++) fa[i]=i;//初始化头目
16     for(int i=1;i<=n;i++) scanf("%d",&a[i]);
17     
18     for(int i=1;i<=m;i++)
19     {
20         int u,v;
21         scanf("%d%d",&u,&v);
22         fa[ff(u)]=ff(v); //合并小组   
23     }
24     for(int i=1;i<=n;i++)
25     { 
26         mx[ff(i)]=max(mx[ff(i)],a[i]);
27         sz[ff(i)]++;
28     }//把小组里糖果最大需求量和小组人数单独统计
29     long long ans=0;//同样是long long
30     for(int i=1;i<=n;i++) ans+=(long long)sz[i]*mx[i];
31     cout << ans;
32     return 0;
33 }

 

posted @ 2021-02-06 19:43  九州霜  阅读(138)  评论(0编辑  收藏  举报