随笔分类 - 并查集
摘要:经典问题,并查集实现题意:略,几题的分析也略,黑书81页有分析另外网上也能找到很多注意一些特判的情况就不回WA,另外题意描述确实不够准确,稍后更新具体的分析部分1.可能出现两个等式长度不等的情况,直接判为无解2.对于k=0,即没有英文单词只有01的时候只要比较这两个串是否相同即可,相同结果为1,不同为0,其实不需要特判也行,但是我采用了特判3.不同字母可以用相同的01表示,好像a,b,按理说是不同的字母应该有不同的表示,不能一样,但是是允许的,即可以同时为某个01组合4.没用上的英文单词也需要计算在内好像32 2 22ab2ab答案是多少?应该是2^2*2^2=16?,虽然c没有用上,但是也要
阅读全文
摘要:LCA参考Yuan神博客:/*题意:给出一棵节点有值的树,给出Q个询问(a,b),问从a到b的最大盈利(即:先在最小值买入,再在最大值卖出)我有想过用一个新序列w2-w1,w3-w2,,wn-wn-1这样只需用O(n)求得最大子段和即为结果Max-Min了但Q很大,每次都找一个路径会超时用类似Tarjan算法进行处理,但在find()那里要修改一下对每个几点记录4个值up[v]表示从v到目前的根的最大盈利down[v]从目前的根到v的最大盈利Max[v]表示到目前的根的最大值Min[v]表示到目前的根的最小值转移看update!在LCA(u,v)处再来计算,这样那四个值才是正确的值!!*/#i
阅读全文
摘要:并查集题意:题意比较好懂简单说一下。一个序列,只有0,1;输入n,表示序列长度(从1到n标号),输入m,下面m个更新,每行都是a,b,string,表示说序列中下标a到下标b的元素中有偶数个或奇数个1.没得到一个更新就更新序列的信息,知道读入第k个信息,和已建立的信息矛盾,那么结束,输出k-1,表示前面k-1个更新不矛盾,如果m个更新都成立,那么输出m这题要转化一下,一转化就比较明显了。我们定义前缀和为sum[i]表示1到i的和,那么sum[b]-sum[a-1]=c[a]+c[a+1]+c[a+2]……c[b] , 即序列的[a,b]区间和因为序列中只有0,1所以区间和的奇偶性就是该区间拥有
阅读全文
摘要:并查集选拔赛的题目。题意:如图所示是一些六边形的单元,一开始初始化所有的单元都是海洋,然后给你一个序列,就是一个单元坐标的序列。如果这个单元是个海洋,看能不能把它变成陆地,能变成陆地的条件是,如果它周围(也就是和它直接相连的那六个单元)已经是陆地,加入这块会使总陆地面积变大,但是面积有个限制值s,一块陆地的总面积不能超过s,如果加入这块不超过限制那么就加入,并且这个块海洋变成了陆地,如果超过了限制值那么这块单元要忽略,依然是海洋。如果是这块单元已经是陆地了,那么直接跳过。一整块陆地的总面积就是它拥有的单元数要你输出最后有多少块大陆地,每一块的面积是多少,面积按升序输出这里要注意,好像(1,1)
阅读全文
摘要:并查集经典题目,详细写一下吧题意:虽然比较长,但是题意还是比较好懂的。如果a和b是朋友,b和c是朋友,那么a和c是朋友。如果a和b是敌人,c和b是敌人,那么a和c要成为朋友操作1和2是假设(或者说试图建立某种关系),如果能成立不用输出,并且保持这种关系,如果这种假设(关系)与之前已经存在的关系是冲突的,那么输出-1,并且要保持原来的关系,放弃当前这个失败的。操作3和4是判断,即根据当前已知的关系,判断某两个人之间的关系是否成立,成立输出1,不成立或者无法确定就输出01 a b 即试图让a和b成为朋友唯一不成立是:a在b的敌对集合中(那么同时b一定在a的敌对集合中)a和b有共同敌人,成立a和b至
阅读全文
摘要:并查集裸题,可以用来学习并查集的性质1.并查集判断是否成环,如果一条边的两个点的祖先相同,那么成环2.整个祖先数组中p[i]=i个个数就是连通分量的个数题目要求:1.若没哟普任何边直接输入0 0 要输出Yes2.若成环,No3.不管是否成环,图不连通,No4.注意输入中的点是任意的,编号并不连续,所以要标记哪些点出现在输入中,没有出现在输入中的点不要管#include <cstdio>#include <cstring>#define N 100010int p[N],use[N];int find(int x){ while(x!=p[x]) x=p[x]; ret.
阅读全文
摘要:纯粹考察并查集,算是一个经典问题;统计一个集合中有多少个元素,然后找到元素个数最多的集合就普通的并查集,就能过了然后另外写了压缩路径,没想到时间没有改变然后再写一个,时间还是没有改变,好吧……………………只要懂基本的并查集的话,代码都不成问题,很裸的并查集而已代码一:纯粹#include <cstdio>#include <cstring>#define N 30000int p[N],c[N];int n,m;int find(int x){ return p[x]==x ? x : p[x]=find(p[x]); }int main(){ int T; scanf
阅读全文
摘要:2012-11-23今天复习了一下并查集,然后这道题才发现当时是傻掉了,其实就是并查集找有多少个连通分量,有c个连通分量的话要把他们连起来就需要c-1条边,根本不需要kruskal算法…………………………#include <cstdio>#include <cstring>#define N 1010int p[N];int n,m;int find(int x){ return p[x]==x ? x : p[x]=find(p[x]); }int main(){ while(scanf("%d",&n) && n) { f
阅读全文

浙公网安备 33010602011771号