当前位置:   article > 正文

树状数组-并查集_删除边 仍然联通的最大权值和

删除边 仍然联通的最大权值和

1.树状数组

给你一个序列a[1]~a[N],你需要找出每一个数a[i],在区间[1, i - 1]有多少个数小于等于a[i]。

  1. int lowbit(int x)
  2. {
  3. return x&(-x);
  4. }
  5. void update(int x,int y)
  6. {
  7. while(x<=n)
  8. {
  9. c[x]+=y;
  10. x+=lowbit(x);
  11. }
  12. //return;//重点
  13. }
  14. int sum(int x)
  15. {
  16. int ans=0;
  17. while(x>0)
  18. {
  19. ans+=c[x];
  20. x-=lowbit(x);
  21. }
  22. return ans;
  23. }

给你一个初始全为0的序列a[1]~a[N],有q次操作,每次操作有两种类型,第一种操作时区间翻转操作,将区间[l, r]进行翻转,也就是原来为0的数现在变为1,原来为1的数现在变为0.第二组是查询操作,查询位置loc的值是0还是1.

  1. int lowbit(int x)
  2. {
  3. return x&(-x);
  4. }
  5. void update(int l,int r)
  6. {
  7. while(l>0)
  8. {
  9. w[l]+=1;
  10. l-=lowbit(l);
  11. }
  12. while(r>0)
  13. {
  14. w[r]+=1;
  15. r-=lowbit(r);
  16. }
  17. }
  18. int sum(int x)
  19. {
  20. int sum=0;
  21. while(x<=N)
  22. {
  23. sum+=w[x];
  24. x+=lowbit(x);
  25. }
  26. return sum;
  27. }

2.并查集

把这些柱子当成N个节点,编号为1~N,然后给你若干条边,每条边连接两个点,且每条边有一个权值。现在让你删去其中的若干条边,使得这N个节点相互连通。当然有很多种不同的删法,现在让你找出一种删法,使得删除的边的权值和最大,如果不存在删法,使得这N个节点相联通,输出-1,否则,输出删除的最大边权和。

  1. #include<iostream>
  2. #include<vector>
  3. #include<algorithm>
  4. using namespace std;
  5. struct edge
  6. {
  7. int u, v;
  8. int w;
  9. friend bool operator < (edge a, edge e)
  10. {
  11. return a.w<e.w;
  12. }
  13. }e[1000000];
  14. vector<edge> part;
  15. vector<long> father(1000000, -1);
  16. long findfather(long i)
  17. {
  18. if (father[i] == -1) return i;
  19. else return father[i] = findfather(father[i]);
  20. }
  21. void merge_union(long x, long y)
  22. {
  23. long f1 = findfather(x);
  24. long f2 = findfather(y);
  25. father[f1] = f2;
  26. }
  27. long findmin(long n)
  28. {
  29. sort(part.begin(), part.end());
  30. vector<edge> mst;
  31. long sum = 0;
  32. long x = 0;
  33. for (long i = 0; i<part.size(); i++)
  34. {
  35. if (findfather(part[i].u) == findfather(part[i].v)) continue;
  36. else
  37. {
  38. merge_union(part[i].u, part[i].v);
  39. sum += part[i].w;
  40. mst.push_back(part[i]);
  41. }
  42. }
  43. if (mst.size() != n - 1) return -1;
  44. return sum;
  45. }
  46. int main()
  47. {
  48. long N,M;
  49. long T;
  50. cin >> T;
  51. while (T--)
  52. {
  53. cin >> N >> M;
  54. long x,sum=0;
  55. for (long i = 0; i<M; i++)
  56. {
  57. edge ed;
  58. cin >> ed.u >> ed.v >> ed.w;
  59. part.push_back(ed);
  60. sum += ed.w;
  61. }
  62. x = findmin(N);
  63. if (x == -1) cout << x << endl;
  64. else
  65. cout << sum-x << endl;
  66. part.clear();
  67. father.clear();
  68. father.resize(1000000, -1);
  69. }
  70. return 0;
  71. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/227646
推荐阅读
相关标签
  

闽ICP备14008679号