• D. Social Network(并查集修改连通块数量)


    Problem - D - Codeforces

     

    威廉来到了一个专门讨论加密货币的会议。要想了解加密货币世界的最新消息,建立联系、认识新朋友、利用朋友的关系是必不可少的。

    会议有N个参与者,他们最初都不熟悉对方。威廉可以把之前不熟悉的任何两个人a和b介绍给对方。

    威廉有d个条件,其中第i个条件要求人xi与人yi有联系。从形式上看,如果有这样一条链p1=x,p2,p3,...,pk=y,对于1到k-1的所有i来说,编号为pi和pi+1的两个人确实认识对方,则两个人有联系。

    对于每一个i(1≤i≤d),威廉希望你能计算出一个人能够拥有的最大的熟人数量,假设威廉满足了从1到i(包括i)的所有条件,并且正好进行了i次介绍。这些条件是在威廉进行了i次介绍之后被检查出来的。每个i的答案必须独立计算。这意味着,当你计算i的答案时,你应该假设还没有两个人被介绍给对方。

    输入
    第一行包含两个整数n和d(2≤n≤103,1≤d≤n-1),分别是人的数量和条件的数量。

    接下来的d行各包含两个整数xi和yi (1≤xi,yi≤n,xi≠yi),根据条件i必须有联系的人数。

    输出
    如果William进行了i次介绍并满足了前i个条件,则第i个数字必须等于拥有最大可能的熟人的人数。

    例子
    输入复制
    7 6
    1 2
    3 4
    2 4
    7 6
    6 5
    1 7
    输出拷贝
    1
    1
    3
    3
    3
    6
    输入复制
    10 8
    1 2
    2 3
    3 4
    1 4
    6 7
    8 9
    8 10
    1 4
    输出拷贝
    1
    2
    3
    4
    5
    5
    6
    8
    备注
    对第一个测试案例的解释。

    在这个解释中,圆圈和其中的数字表示具有相应数字的人。这条线表示威廉介绍了两个有联系的人。标记为红色的人有最多的熟人。这些并不是介绍人的唯一正确方法。

    题解:
    我们每次并查集找x,y是否连接

    如果未连接,我们就应该让他们连接上,清空其中一个块的数目,加到另一个块上,并且连接他们

    如果已经连接.那我们就有额外一次连接机会k++(初始为1),排序找到前k个最大的相加ans

    答案为ans - 1

    1. #include<iostream>
    2. #include<vector>
    3. #include<queue>
    4. #include<cstring>
    5. #include<algorithm>
    6. #include<string>
    7. #include<map>
    8. using namespace std;
    9. #define int long long
    10. int f[1030];
    11. int siz[1030];
    12. int w[1030];
    13. int find(int x)
    14. {
    15. if(f[x] == x)
    16. return x;
    17. return f[x] = find(f[x]);
    18. }
    19. void solve()
    20. {
    21. ios::sync_with_stdio(false);
    22. cin.tie(0);
    23. cout.tie(0);
    24. int n,m;
    25. cin >> n >>m;
    26. for(int i = 1;i <= n;i++)
    27. {
    28. f[i] = i;
    29. siz[i] = 1;
    30. }
    31. int cnt = 1;
    32. while(m--)
    33. {
    34. int x,y;
    35. cin >> x >> y;
    36. if(find(x) == find(y))
    37. {
    38. cnt++;
    39. }
    40. else
    41. {
    42. siz[find(x)] += siz[find(y)];
    43. siz[find(y)] = 0;
    44. f[find(y)] = find(x);
    45. }
    46. for(int i = 1;i <= n;i++)
    47. {
    48. w[i] = siz[i];
    49. }
    50. sort(w+1,w+1+n,greater<int>());
    51. int ans = 0;
    52. for(int i = 1;i <= cnt;i++)
    53. {
    54. ans += w[i];
    55. }
    56. cout<<ans-1<<"\n";
    57. }
    58. }
    59. signed main()
    60. {
    61. int t = 1;
    62. // cin >> t;
    63. while(t--)
    64. {
    65. solve();
    66. }
    67. }

  • 相关阅读:
    Mybatis缓存
    Git创建仓库、并同步本地项目到远程
    【项目经理】工作流引擎
    第四章 神经网络的学习——数据&损失函数&数值微分&神经网络的梯度&学习算法的实现
    vue开发-语法和基础流程规范
    【Flask基础】九,Flask--蓝图模块划分介绍(使用蓝图+不使用蓝图)
    基于SSM框架的《超市订单管理系统》Web项目开发(第三天)用户管理,模糊查询,精准匹配,分页显示数据
    Kubernetes
    5. 【线索二叉树】的由来、基本概念、结构体定义、三种遍历线索化、线索二叉树找前驱/后继
    String常见算法(一)
  • 原文地址:https://blog.csdn.net/m0_64158084/article/details/128139648