22牛客多校day1 J - Serval and Essay 启发式合并
J - Serval and Essay
Serval is a new student in Japari Kindergarten.
Could you help him find out the answer?
Each test contains multiple test cases.
3
4
0
1 1
2 1 2
2 2 3
5
1 3
1 1
1 2
1 5
4 1 2 3 4
7
0
2 1 4
1 2
1 3
2 3 4
1 1
2 5 6
输出样例:
Case #1: 4
Case #2: 3
Case #3: 4
样例解释
For the first sample, Serval can set the 111-st argument as the argument basis to obtain 444 true arguments in the essay. The following process shows how Serval makes conclusions in his essay.
⋅ Set the 111-st argument as the argument basis, which is regarded as true.
⋅ Conclude that 222-nd argument is true because 111-st argument is true.
⋅ Conclude that 333-rd argument is true because both 111-st and 222-nd arguments are true.
⋅ Conclude that 444-th argument is true because both 222-nd and 333-rd arguments are true.
题意
给定一张有向无环图,有 nnn 个点均为白色,开局可以选定一个点将其染成黑色,若一个点的前置节点均为黑色,那么这个点也可以染成黑色。求最多能染成黑点的个数。
思路
对于入度为 111 的节点,与其选这个节点不如选她的父节点,因为将其父节点染黑后她的前置节点全为黑色,这个节点也能染黑。于是可以将这两个节点合并,子节点原本的出边也要合并到父节点上。考虑到这两点可能存在的公共边需要减少存在公共出边的节点的入度。若减少入度之后的子节点的入度变为了 111 则又可以重复上述的合并操作。
最终会得到若干个连通块,答案便是 sizesizesize 最大的连通块的 sizesizesize。
维护连通块以及连通块的 sizesizesize 用并查集即可。
对于合并操作需要合并两个集合的边,在最坏情况下需要合并 n−1n-1n−1 次,若是将两个集合的边都遍历一遍去判断重边复杂度会达到 O(m2)O(m^2)O(m2) 显然是不允许的。此时合并操作便可以用启发式合并去做,启发式合并对于两个集合合并的操作,每次将 sizesizesize 小的集合合并到sizesizesize 更大的集合中去。易证 启发式合并的时间复杂度为 O(nlogn)O(nlogn)O(nlogn) 对于每个元素所处的集合的每次合并都会使得集合的大小至少乘以2,故一个集合最多被合并 log2nlog_2nlog2n 次。故我们将每个集合的出边存到一个 setsetset 中,每次将 sizesizesize 小的集合的边插入到 sizesizesize 大的集合的 setsetset 中即可。而且 setsetset 会自动去重,这样复杂度乘上 setsetset 的 logloglog 可以做到 O(mlog2m)O(mlog^2m)O(mlog2m) 。
Code
#include<bits/stdc++.h>
using namespace std;
#define __T int csT;scanf("%d",&csT);while(csT--)
#define endl '\n'
const int mod=998244353;
const double PI= acos(-1);
const double eps=1e-6;
const int N=2e5+7;int n,k,v,ans;
int fa[N],sz[N];
set<int> to[N],fr[N];int find(int x)
{if(fa[x]==x)return x;return fa[x]=find(fa[x]);
}
void merge(int x,int y)
{x=find(x);y=find(y);if(x==y)return;//若两个集合已经合并就returnif(to[x].size()>to[y].size())swap(x,y);//默认x为小的集合fa[x]=y;sz[y]+=sz[x];vector<pair<int,int>> vc;for(set<int>::iterator it=to[x].begin();it!=to[x].end();++it){to[y].insert(*it);//将x的出边加到y的出边fr[*it].erase(x);//删除原本x出边指向点的入边fr[*it].insert(y);//加上x出边指向点y的入边if(fr[*it].size()==1){vc.push_back({*it,y});}}for(int i=0;i<vc.size();++i){merge(vc[i].first,vc[i].second);}
}int cs;
int main()
{cs=0;__T{scanf("%d",&n);for(int i=1;i<=n;++i){fa[i]=i;sz[i]=1;to[i].clear();fr[i].clear();}for(int i=1;i<=n;++i){scanf("%d",&k);for(int j=1;j<=k;++j){scanf("%d",&v);to[v].insert(i);fr[i].insert(v);}}//对于每个点用set存入边和出边for(int i=1;i<=n;++i){if(fr[i].size()==1)//入边为1意味着可以合并{merge(i,*fr[i].begin());}}ans=0;for(int i=1;i<=n;++i){ans=max(ans,sz[i]);}printf("Case #%d: %d\n",++cs,ans);}return 0;
}
22牛客多校day1 J - Serval and Essay 启发式合并相关推荐
- 22牛客多校day1 I - Chiitoitsu 概论dp
I - Chiitoitsu 题目背景 Serval is learning Japanese Mahjong recently in order to play Mahjong Soul with ...
- 2021牛客多校1——J:Journey of Railway Stations(线段树)
题面 题意: 一段路上有 N N N 个火车站,每个火车站有一个合法时间段 [ u i , v i ] [u_i, v_i] [ui,vi],相邻两个火车站有一个长度 c o s ...
- 图论 ---- Tajran找割点 牛客多校2021 J Defend Your Country
解题思路: 首先我们知道对于点数为偶数的联通块是不用管的 对于奇数个连通块里面的点: 点分两种: 普通的点:对于奇数个点的连通块,删除一个普通点就很好了.那么就是删除那个权值最小的普通点就可以了 割点 ...
- 牛客练习赛63 F.牛牛的树行棋(启发式合并+sg打表)
LINK 假设只有一枚棋子,那么这枚棋子在叶子节点的 s g sg sg值显然是零 其他节点可以 s g sg sg打表推出来,由于只需要子树内的 s g sg sg值,似乎需要用到启发式合并计算 但 ...
- 牛客多校三 B Black and white
牛客多校三 B Black and white 在n*m的棋盘上,每个格子有一个数,初始可以选一定的格子标记为黑色,在任意四个形如(i1, j1)(i1, j2)(i2, j1)(i2, j2)的格子 ...
- 2019牛客多校第一场
2019牛客多校第一场 题号 题目 知识点 A Monotonic Matrix B Symmetric Matrix C Fluorescent 2 D Two Graphs E Removal F ...
- LCS(2021牛客多校4)
LCS(2021牛客多校4) 题意: 让你构造三个字符串s1,s2,s3,长度均为n,要求LCS(s1,s2)=a,LCS(s2,s3)=b,LCS(s1,s3)=c 题解: 先考虑三个串互相LCS为 ...
- 24dian(牛客多校第三场)
24dian(牛客多校第三场) 题意: 给你n张牌,每张牌的大小为1 ~ 13,问这些牌与加减乘除任意组合(可以使用括号),且但所有的有效解在计算过程中都涉及到分数,即非整数,能否组成答案m,如果可以 ...
- 2018年牛客多校算法寒假训练营练习比赛(第一场)C. 六子冲
2018年牛客多校算法寒假训练营练习比赛(第一场)C. 六子冲 题目链接 做法:模拟即可 #include <bits/stdc++.h> #define P pair<int,in ...
- 2022牛客多校(十)
2022牛客多校(十) 一.比赛小结 比赛链接:"蔚来杯"2022牛客暑期多校训练营10 二.题目分析及解法(基础题) F.Shannon Switching Game? 题目链接 ...
最新文章
- 初识Zookeeper
- Maven入门指南:仓库
- java matcher group_JAVA正则表达式matcher.find()和 matcher.matches()的区别
- 为什么不建议你使用实数作为 HashMap 的key?
- JavaScript里的函数加或不加括号的区别
- Kubernetes常见操作
- 20. 远程端口查看
- Process Monitor工具找网吧广告
- fatal:unable to access ‘https://github....‘:Failed to conect to github.com port 443:拒绝连接的解决方法
- 63 Defi过后,人生第一次玩DAO----超级君【2020-08-22 2234】
- LSF Command
- ROS-moveit!仿真出现问题:Unable to identify any set of controllers that can actuate the specified
- poi word表格系列操作
- 双宾语与复合宾语,分词状语与独立主格状语
- 《匆匆那年》的你,还记得吗?数学中的那些有(hui)趣(se)的定理(13)——绝妙定理
- 共享自习室无人自习室源码
- 闽南师范大学有计算机培训班吗,闽南师范大学计算机技术专业学位研究生招生简章...
- Flickr相片平台正式继续保留CC授权照片
- 一文了解 , 什么样的邮箱最好用?企业邮箱活动有哪些?
- 基于proteus的一个硬布线CPU