[关闭]
@WangYixu 2018-06-15T11:26:18.000000Z 字数 585 阅读 999

[NOI2002]银河英雄传说

OI 题解 并查集

算法:并查集(带权)

代码分析:

带权并查集:

注意这个题要存每组的大小,因为题意是要合并到队列末端,而不是j的后面

  1. int fa[N], d[N], s[N];
  2. // 父节点,到父节点的距离,每组的大小
  3. int find(int x) {
  4. if(fa[x] == x) {
  5. return x;
  6. }
  7. int pre = fa[x];
  8. int ft = find(fa[x]);
  9. d[x] = d[pre] + d[x];//更新到父节点的距离(此时父节点是根节点)
  10. fa[x] = ft;
  11. return fa[x];
  12. }
  13. int main() {
  14. cin >> n;
  15. char op;
  16. int x, y;
  17. int ans, fx, fy;
  18. //初始化并查集
  19. for(int i = 1; i <= N; ++i) {
  20. fa[i] = i;
  21. s[i] = 1;
  22. }
  23. for(int i = 1; i <= n; ++i) {
  24. cin >> op >> x >> y;
  25. fx = find(x);
  26. fy = find(y);
  27. if(op == 'M') {
  28. if(fx != fy) {
  29. //合并
  30. fa[fx] = fy; //直接合并到并查集根节点后
  31. d[fx] += s[fy];//但是距离依旧模拟合并到队列后边
  32. s[fy] += s[fx];
  33. }
  34. } else if(op == 'C') {
  35. if(fx != fy) {
  36. ans = -1;
  37. } else {
  38. ans = abs(d[x] - d[y]) - 1;//别忘了减一
  39. }
  40. printf("%d\n", ans);
  41. }
  42. }
  43. return 0;
  44. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注