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

来源:互联网 发布:php淘宝客系统 编辑:程序博客网 时间:2024/05/17 04:56
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