【NOIP practice】BSOJ 3132 卡扎菲 并查集

29 篇文章 0 订阅
11 篇文章 0 订阅
3132 -- 【刘峻琳day1-2】卡扎菲
Description
42年前,当一个帅气的年轻军官推翻了利比亚的封建独裁,所有人都认为利比亚的好日子要来了。但正如历史上大多数统治者一样,长期的统治只不过会膨胀其独裁的野心,卡扎菲未能幸免地将利比亚带入了下一个黑暗的时期。2011年,在北约的帮助下,利比亚反对派终于向这位暴君宣战。反对派有n个人,一开始他们各自为战(即各自为一个单独的部队),在全国各地点燃硝烟。随着战事的进行,他们中的一些部队为了合并力量或者因为占领地相邻而将两支队伍合并,以期以更猛的攻势摧毁卡扎菲政权。卡扎菲方面,由于正义终将战胜邪恶,越来越多的卡军向反对派投诚,卡军的力量受到极大的削弱。无奈之下,卡军只有集中精力攻打一支反动军队,卡扎菲需要知道此时此刻力量最大的部队是哪一支。
Input
输入第一行包含两个整数n,m,表示最初部队个数和操作个数。
接下来m行,每一行第一个整数为k。若k为1,表示此时有两支反军合并,后面紧跟两个整数x,y,表示士兵x和士兵y所在的部队此时合并,若x和y已在同一部队,则忽略此信息;若k为2,则表示卡扎菲发出一条询问,询问此时人数最多的部队。
Output
对于每一条询问,你需要输出人数最多的部队的人数。
Sample Input
2 3
2
1 1 2
2
Sample Output
1
2
Hint
对于50%的数据n,m<=1000

对于100%的数据n,m<=100000, 1<=x,y<=n


裸并查集..每次合并把两个集合的sum修改为sum1+sum2.每次合并维护最大值,输出即可。

然而我一开始是每次询问for循环查找一次..TLE 5组。


#include<iostream>
#include<iomanip>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
void File_Format()
{
	freopen("rebell.in","r",stdin);
	freopen("rebell.out","w",stdout);
}
int prt[500005]={0},n,m,cnt[500005]={0};
int getfa(int x)
{
	if(x==prt[x])return x;
	return prt[x]=getfa(prt[x]);
}
void work()
{
	int cmd;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)prt[i]=i,cnt[i]=1;
	int maxx=1;
	for(int i=1;i<=m;i++)
	{
	  scanf("%d",&cmd);
	  if(cmd==1)
	  {
		int x,y;
		scanf("%d%d",&x,&y);
		int f1=getfa(x);
		int f2=getfa(y);
		if(f1!=f2)
		{
			prt[f1]=f2;
			cnt[f1]=cnt[f2]=cnt[f1]+cnt[f2];maxx=max(maxx,cnt[f1]);
	    }
	  }	
	  if(cmd==2)printf("%d\n",maxx);
	}
}
int main(){
	work();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值