Evanyou Blog 彩带

洛谷P1196 [NOI2002] 银河英雄传说

  题目传送门

  首先分析题目,数据范围特别大,500000组询问直接模拟肯定会超时,这里其实很容易可以想到用并查集。我们定义三个数组:fa[]表示每一个飞船的队首,front[]表示每一搜飞船到队首的距离,num[]表示以该飞船为队首的队伍中飞船的数量。每次M操作时就将x的队首的num值清空,并将fa值改变为y的队首,再将front值更新即可。询问时只要判断fa是否相等就可以了,不相等的话直接输出-1,否则输出abs(front[x]-front[y])-1。

  Code:

 

复制代码
  1. #include<cstdio>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<cmath>
  5. #include<iomanip>
  6. #include<iostream>
  7. #include<algorithm>
  8. using namespace std;
  9. const int N=3e4+7;
  10. int n,fa[N],dis[N],cnt[N];
  11. inline int read()
  12. {
  13. char ch=getchar();int num=0;bool flag=false;
  14. while(ch<'0'||ch>'9'){if(ch=='-')flag=true;ch=getchar();}
  15. while(ch>='0'&&ch<='9'){num=num*10+ch-'0';ch=getchar();}
  16. return flag?-num:num;
  17. }
  18. inline int Abs(int x)
  19. {return x>0?x:-x;}
  20. inline int find(int x)
  21. {
  22. if(fa[x]==x)return x;
  23. int fx=find(fa[x]);
  24. dis[x]+=dis[fa[x]];
  25. return fa[x]=fx;
  26. }
  27. int main()
  28. {
  29. n=read();
  30. char s;int x,y;
  31. for(int i=1;i<=30000;i++)
  32. fa[i]=i,dis[i]=0,cnt[i]=1;
  33. for(int i=1;i<=n;i++){
  34. cin>>s;
  35. x=read();y=read();
  36. int fx=find(x),fy=find(y);
  37. if(s=='M'){
  38. if(fx==fy)continue;
  39. dis[fx]+=cnt[fy];
  40. fa[fx]=fy;
  41. cnt[fy]+=cnt[fx];
  42. cnt[fx]=0;}
  43. else{
  44. if(fx!=fy)printf("-1\n");
  45. else printf("%d\n",Abs(dis[x]-dis[y])-1);
  46. }
  47. }
  48. return 0;
  49. }
复制代码

 

 

  

 

posted @   HolseLee  阅读(211)  评论(0编辑  收藏  举报
编辑推荐:
· 现代计算机视觉入门之:什么是图片特征编码
· .NET 9 new features-C#13新的锁类型和语义
· Linux系统下SQL Server数据库镜像配置全流程详解
· 现代计算机视觉入门之:什么是视频
· 你所不知道的 C/C++ 宏知识
阅读排行:
· 不到万不得已,千万不要去外包
· C# WebAPI 插件热插拔(持续更新中)
· 会议真的有必要吗?我们产品开发9年了,但从来没开过会
· 【译】我们最喜欢的2024年的 Visual Studio 新功能
· 如何打造一个高并发系统?
点击右上角即可分享
微信分享提示