首页 > 其他分享 >poj 1988(并查集)

poj 1988(并查集)

时间:2023-05-29 22:35:12浏览次数:32  
标签:cnt int top 查集 1988 fa poj maxn find


题意:进行m次操作,M x y 将包含x的集合移动到y上面,C x, 计算x下面有几个元素。


解题思路:这道题很容易想到用并查集,但是这里有点绕;最开始我想到的是建立一个num[x],表示x以下的节点数,但这样会有一个问题,要更新num[x]时,必须要枚举哪些节点的父节点为p,由于节点数太多,所以TLE是难免的。。。。






这里有一个好办法:在算x以下节点数时,可以用x所在集合元素的个数 - 在它之上的个数 - 它本身。这样就可以避免枚举了。


AC:


#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn = 30005;
int fa[maxn],cnt[maxn],top[maxn];

int find(int x)
{
	if(fa[x] == x) return x;
	int t = fa[x];
	fa[x] = find(fa[x]);
	top[x] += top[t];
	return fa[x];
}

void Union(int x,int y)
{
	int fx = find(x);
	int fy = find(y);
	if(fx != fy)
	{
		fa[fy] = fx;
		top[fy] = cnt[fx];
		cnt[fx] += cnt[fy];
	}
}

int main()
{
	int p,a,b;
	char ch;
	for(int i = 1; i < maxn; i++)
	{
		fa[i] = i;
		top[i] = 0;
		cnt[i] = 1;
	}
	scanf("%d",&p);
	while(p--)
	{
		getchar();
		ch = getchar();
		if(ch == 'M')
		{
			scanf("%d%d",&a,&b);
			Union(a,b);
		}
		else 
		{
			scanf("%d",&a);
			int f = find(a);
			printf("%d\n",cnt[f] - top[a] - 1);
		}
	}
	return 0;
}



标签:cnt,int,top,查集,1988,fa,poj,maxn,find
From: https://blog.51cto.com/u_16143128/6374327

相关文章

  • poj 1230(贪心)
    解题思路:这道题目是用贪心的思想,从左向右扫描场地的每一列是否合法。若不合法,贪心的找出从该列起向右延伸最长的m道墙,移除这m道墙使得该列合法。我最开始代码会出现这样的问题:如果两个墙是连在一起的,那么会被当做一个墙来处理。。。AC:#include<iostream>#include<cstdio>#inclu......
  • poj 1634
    题意:一个员工A的直接上司是那些薪水大于A,并且身高>=A的人中薪水最少的一个。主席CEO的薪水最高,且身高也是最高的。有多组数据。每组数据给出m个员工,和q个询问。每个员工有id、薪水、身高。对于每个询问,给出某个id,让你求该员工的直接上司的id和该员工的下属的个数。若该员工......
  • poj 1451(Trie)
    题意:就是让你模拟手机输入单词。具体就是给你一些单词,以及该单词被使用的频数,这个频数也是该单词前缀的使用频数,当然不同的单词有可能有相同的前缀,那么这个相同的前缀的使用频数就是这两个单词使用频数之和,以此类推。然后再给你一些数字串,让你针对该数字串的每一个前缀输出它的最有......
  • poj 1190(剪枝)
    生日蛋糕TimeLimit: 1000MS MemoryLimit: 10000KTotalSubmissions: 16191 Accepted: 5751Description7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体。 设从下往上数第i(1<=i<=M)层蛋糕是半径为Ri,高度为Hi的圆......
  • poj 3281(最大流)
    解题思路:这是道匹配的问题,最近刚学网络流,所以想用网络流去做。。按照题目要求,我开始建立的是food----cow----drink的图,源点与所有的food的编号连接,所有的drink的编号与汇点连接,这里所有的有向边的容量都为1,。。但很不幸的是WA了。。看了别人的思路,我才知道原来这里保证不了一头牛......
  • poj 1935(搜索+回溯)
    解题思路:先我们考虑从源点出发到所有自己想要经过的点然后在回到源点sum,显然每条边都必须经过源点(这个我们可以一次dfs求出),但题目的意思是可以不用回到源点,那么我们可以再求源点到所有要经过的点的最远距离ans,于是答案便是sum-ans.这道题的思路确实是很巧妙,一开始我还是在想如......
  • poj 2346(DP)
    题意:n位数,满足前n/2个数字之和同后n/2个数字之和相同的数一共有多少个?解题思路:dp[i][j]表示前i个数的和为j时,有多少个;递推关系:dp[i][j]+=dp[i-1][k],k表示前i-1个数的和,由于每一位只能是0-9,所以有限制条件:9>=j - k>=0由于对称性,只需要枚举到n/2即可,剩下的就是简单的乘法......
  • poj 2415(BFS)
    题意: 有一种游戏,共有三个piece(不妨称为棋子),棋盘是由N个点构成的完全图,边有颜色。每次可以移动一个棋子,移动时必须满足棋子走过的边的颜色和其他两个棋子之间的连边的颜色一致。求把三个棋子移到同一个顶点的最少次数。这道题是一个很简单的BFS,但为何一直TLE。。。。#include<ios......
  • poj 1054
    解题思路:这道题其实比较简单,就是找斜率相同且间距相同的点。首先,就是要找到两点,确定好斜率,然后就判断这两点是否在起始位置。其次,确定好斜率就确定了两个点之间的距离,如果某两点之间的间距不满足的话,那么这个点肯定不是这个方向上的。#include<iostream>#include<cstdio>#include......
  • poj 2010(优先队列)
    题意:奶牛大学:奶大招生,从C头奶牛中招收N头。它们分别得分score_i,需要资助学费aid_i。希望新生所需资助不超过F,同时得分中位数最高。求此中位数。解题思路:这里要求最大中位数,中位数肯定是在这些人中间,故可以枚举中位数,可以先对分数进行排序,然后用二分去找最大中位数。每次枚举的中位......