题目大意:

有 \(n\) 名员工,一共有 \(m\) 种语言,每名员工都会其中 \(k_i\) 种语言(\(m \ge \boldsymbol{k_i \ge 0}\)),现规定两名员工可以交流的条件如下:

  1. 两名员工会一种及以上共同的语言。
  2. 有一名员工可以当这两名员工的翻译(即有一名员工会这两名员工会的语言中的各一种)。

问每位员工所需要学习的语言数的和为多少。

题目分析:

我们可以对能够交流的员工建图,然后不难发现以下性质:

  1. 若 \(A\) 可以和 \(B\) 交流,则 \(B\) 也可以和 \(A\) 交流(即无向性)。
  2. 若 \(A\) 可以和 \(B\) 交流,\(B\) 可以和 \(C\) 交流,则 \(A\) 也可以和 \(C\) 交流(即传递性)。

所以,此时的问题就变成了给定一张无向图,问加几条边能够使其成为一张连通图。

可能有更好的做法,但我的做法如下:

  1. 若该点表的员工一种语言也不会,则 \(cnt\) 加一。
  2. 若该点没有被访问过,且该点表示的员工至少会一种语言,则 \(cnt\) 加一,然后以该点为起点进行 \(\operatorname{dfs}\)。
  3. 若该点被访问过,则跳过。

此时答案是 \(cnt - 1\)。

注意:若没有员工会语言,则此时的答案是 \(cnt\) 而不是 \(cnt-1\),因为每一名员工都要学一种语言才能交流。

综上,时间复杂度 \(O(n \times m)\),主要取决于建图部分的时间复杂度。

代码实现:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define TIME_LIMIT (time_t)1e3
#define dbg(x) cerr<<#x<<": "<<x<<endl;
#define MAX_SIZE (int)2.1e4
vector <int> hashtable[MAX_SIZE];
unordered_map <int, bool> edges;
int head[MAX_SIZE];
int ver[MAX_SIZE];
int Next[MAX_SIZE];
int tot = 0;
void add(int u,int v){
ver[++tot] = v;
Next[tot] = head[u];
head[u] = tot;
}
bitset<MAX_SIZE>vis;
bitset<MAX_SIZE>pass;
void dfs(int step, int u, int fa){
assert(step<=114);
vis[u] = 1;
for(int i=head[u];i;i=Next[i]){
int v = ver[i];
if(v==fa)
continue;
if(v==u)
continue;
if(!vis[v])
dfs(step+1,v,u);
}
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef LOCAL
#undef cout
#undef cin
ifstream cin("in.in");
ofstream cout("out.out");
assert(cin.is_open());
assert(cout.is_open());
freopen("in.in","r",stdin);
freopen("out.out","w",stdin);
time_t cs = clock();
#endif
//========================================
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
int k;
cin>>k;
for(int j=1;j<=k;j++){
int lang;
cin>>lang;
hashtable[lang].push_back(i);
}
}
for(int i=1;i<=m;i++){
auto &vec = hashtable[i];
if(vec.empty())
continue;
int u = vec[vec.size()-1];
pass[u] = 1;
vec.pop_back();
for(auto v:vec){
if(!edges[min(u,v)*100+max(v,u)]){
add(u,v);
add(v,u);
pass[v] = 1;
edges[min(u,v)*100+max(v,u)] = 1;
}
}
}
int cnt = 0;
for(int i=1;i<=n;i++) {
if(!vis[i]&&pass[i]){
dfs(1,i,i);
++cnt;
}
}
int nothing = 0;
for(int i=1;i<=n;i++)
if(!pass[i])
++nothing;
if(nothing==n)
cout<<nothing;
else
cout<<nothing+cnt-1;
//========================================
#ifdef LOCAL
cin.close();
cout.close();
time_t ce = clock();
cerr<< "Used Time: " << ce-cs << " ms."<<endl;
if(TIME_LIMIT<ce-cs)
cerr<< "Warning!! Time exceeded limit!!"<<endl;
#endif
return 0;
}

题解 CF277A的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. Django: Token分发

    Django后台token分发 在settings.py中引入 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'd ...

  2. 园子的商业化努力-阿里云开发者社区合作:RDS MySQL Serverless 免费试用活动

    阿里云开发者社区这个月组织了一个针对"云数据库 RDS MySQL Serverless 版"免费试用用户的做任务活动,上周找园子合作,希望能在园子里推广一下这个活动. 由于时间太 ...

  3. Topic太多,RocketMQ炸了!

    网上博客常说,kafka的topic数量过多会影响kafka,而RocketMQ不会受到topic数量影响. 但是,果真如此吗? 最近排查一个问题,发现RocketMQ稳定性同样受到topic数量影响 ...

  4. 加密解决HTTP协议带来的安全问题

    HTTP协议默认是采取明文传输的,容易被中间人窃听.拦截.篡改,存在安全隐患. 常见提高安全性的方法是对通信内容进行加密,再进行传输,常见的加密方式有 不可逆加密:单向散列函数 可逆加密:对称加密.非 ...

  5. Stack Overflow开发者调查发布:AI将如何协助DevOps

    Stack Overflow 发布了开创性的2023年度开发人员调查报告 [1].报告对 90,000 多名开发人员进行了调查,全面展示了当前软件开发人员的体验.接下来,本文将重点介绍几项重要发现,即 ...

  6. GPT-4 到底能帮你干点啥?

    目录 1. 从哪儿聊起呢 2. 潮起潮退 3. 遇强则强,遇我则-- 3.1 玩法一:辅助技能提升 3.2 镜头背后的故事 3.3 玩法二:综合"技术选型" 3.4 镜头背后的故事 ...

  7. C盘无法创建文件处理

    icacls c:\ /setintegritylevel M 打开终端执行上方命令,亲测可用

  8. 用OLED屏幕播放视频(3): 使用cuda编程加速视频处理

    下面的系列文章记录了如何使用一块linux开发扳和一块OLED屏幕实现视频的播放: 项目介绍 为OLED屏幕开发I2C驱动 使用cuda编程加速视频处理 这是此系列文章的第3篇, 主要总结和记录了如何 ...

  9. linux上搭建Nacos集群(步骤详细,linux小白也能搞定)

    (1)nacos官网:https://github.com/alibaba/nacos/releases/tag/1.2.1下载nacos安装包到window本地(后缀为tar.zip) (2)在li ...

  10. 基于Protege的知识建模实战

    一.Protege简介.用途和特点 1.Protege简介 Protege是斯坦福大学医学院生物信息研究中心基于Java开发的本体编辑和本体开发工具,也是基于知识的编辑器,属于开放源代码软件.这个软件 ...